Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.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         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
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
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
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
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
141 static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
142 {
143         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
144         PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
145         struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
146
147         strcpy(info->driver, DRV_NAME);
148         strcpy(info->version, DRV_VERSION);
149         snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
150                  Adapter->uiFlashLayoutMajorVersion,
151                  Adapter->uiFlashLayoutMinorVersion);
152
153         usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
154 }
155
156 static u32 bcm_get_link(struct net_device *dev)
157 {
158         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
159
160         return Adapter->LinkUpStatus;
161 }
162
163 static u32 bcm_get_msglevel (struct net_device *dev)
164 {
165         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
166
167         return Adapter->msg_enable;
168 }
169
170 static void bcm_set_msglevel (struct net_device *dev, u32 level)
171 {
172         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
173
174         Adapter->msg_enable = level;
175 }
176
177 static const struct ethtool_ops bcm_ethtool_ops = {
178         .get_settings   = bcm_get_settings,
179         .get_drvinfo    = bcm_get_drvinfo,
180         .get_link       = bcm_get_link,
181         .get_msglevel   = bcm_get_msglevel,
182         .set_msglevel   = bcm_set_msglevel,
183 };
184
185 int register_networkdev(PMINI_ADAPTER Adapter)
186 {
187         struct net_device *net = Adapter->dev;
188         PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
189         struct usb_interface *udev = IntfAdapter->interface;
190         struct usb_device *xdev = IntfAdapter->udev;
191
192         int result;
193
194         net->netdev_ops = &bcmNetDevOps;
195         net->ethtool_ops = &bcm_ethtool_ops;
196         net->mtu = MTU_SIZE;    /* 1400 Bytes */
197         net->tx_queue_len = TX_QLEN;
198         net->flags |= IFF_NOARP;
199
200         netif_carrier_off(net);
201
202         SET_NETDEV_DEVTYPE(net, &wimax_type);
203
204         /* Read the MAC Address from EEPROM */
205         result = ReadMacAddressFromNVM(Adapter);
206         if (result != STATUS_SUCCESS) {
207                 dev_err(&udev->dev,
208                         PFX "Error in Reading the mac Address: %d", result);
209                 return -EIO;
210         }
211
212         result = register_netdev(net);
213         if (result)
214                 return result;
215
216         gblpnetdev = Adapter->dev;
217
218         if (netif_msg_probe(Adapter))
219                 dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n",
220                          net->name, xdev->bus->bus_name, xdev->devpath,
221                          net->dev_addr);
222
223         return 0;
224 }
225
226 void unregister_networkdev(PMINI_ADAPTER Adapter)
227 {
228         struct net_device *net = Adapter->dev;
229         PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter;
230         struct usb_interface *udev = IntfAdapter->interface;
231         struct usb_device *xdev = IntfAdapter->udev;
232
233         if (netif_msg_probe(Adapter))
234                 dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n",
235                          net->name, xdev->bus->bus_name, xdev->devpath);
236  
237         unregister_netdev(Adapter->dev);
238 }