]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/bcm/Bcmnet.c
5b466174a5802f844f14db54e8b46b1afa4e6b36
[mv-sheeva.git] / drivers / staging / bcm / Bcmnet.c
1 #include "headers.h"
2
3 struct net_device *gblpnetdev;
4 /***************************************************************************************/
5 /* proto-type of lower function */
6
7 static INT bcm_open(struct net_device *dev)
8 {
9     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
10
11     BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
12     if(Adapter->fw_download_done==FALSE)
13         return -EINVAL;
14         if(Adapter->LinkUpStatus == 1){
15                 if(netif_queue_stopped(Adapter->dev)){
16                         netif_carrier_on(Adapter->dev);
17                         netif_start_queue(Adapter->dev);
18                 }
19         }
20
21         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
22     return 0;
23 }
24
25 static INT bcm_close(struct net_device *dev)
26 {
27    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
28
29     BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
30         if(!netif_queue_stopped(dev)) {
31                 netif_carrier_off(dev);
32             netif_stop_queue(dev);
33         }
34     BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<=====");
35     return 0;
36 }
37
38 static struct net_device_stats *bcm_get_stats(struct net_device *dev)
39 {
40         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
41         struct net_device_stats*        netstats = &dev->stats;
42
43         netstats->rx_packets = atomic_read(&Adapter->RxRollOverCount)*64*1024
44                 + Adapter->PrevNumRecvDescs;
45         netstats->rx_bytes = atomic_read(&Adapter->GoodRxByteCount)
46                 + atomic_read(&Adapter->BadRxByteCount);
47
48         netstats->rx_dropped = atomic_read(&Adapter->RxPacketDroppedCount);
49         netstats->rx_errors  = atomic_read(&Adapter->RxPacketDroppedCount);
50         netstats->tx_bytes   = atomic_read(&Adapter->GoodTxByteCount);
51         netstats->tx_packets = atomic_read(&Adapter->TxTotalPacketCount);
52         netstats->tx_dropped = atomic_read(&Adapter->TxDroppedPacketCount);
53
54         return netstats;
55 }
56
57 static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb)
58 {
59         return ClassifyPacket(netdev_priv(dev), skb);
60 }
61
62
63 /*******************************************************************
64 * Function    - bcm_transmit()
65 *
66 * Description - This is the main transmit function for our virtual
67 *                               interface(eth0). It handles the ARP packets. It
68 *                               clones this packet and then Queue it to a suitable
69 *                               Queue. Then calls the transmit_packet().
70 *
71 * Parameter   -  skb - Pointer to the socket buffer structure
72 *                                dev - Pointer to the virtual net device structure
73 *
74 *********************************************************************/
75
76 static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
77 {
78         PMINI_ADAPTER      Adapter = GET_BCM_ADAPTER(dev);
79         u16 qindex = skb_get_queue_mapping(skb);
80
81         if (Adapter->device_removed || !Adapter->LinkUpStatus)
82                 goto drop;
83
84         if (Adapter->TransferMode != IP_PACKET_ONLY_MODE )
85                 goto drop;
86
87         if (INVALID_QUEUE_INDEX==qindex)
88                 goto drop;
89
90         if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
91                 return NETDEV_TX_BUSY;
92
93         /* Now Enqueue the packet */
94         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
95                         "bcm_transmit Enqueueing the Packet To Queue %d",qindex);
96         spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
97         Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
98         Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
99
100         *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies;
101         ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
102                       Adapter->PackInfo[qindex].LastTxQueue, skb);
103         atomic_inc(&Adapter->TotalPacketCount);
104         spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
105
106         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n");
107
108         /* FIXME - this is racy and incorrect, replace with work queue */
109         if (!atomic_read(&Adapter->TxPktAvail)) {
110                 atomic_set(&Adapter->TxPktAvail, 1);
111                 wake_up(&Adapter->tx_packet_wait_queue);
112         }
113         return NETDEV_TX_OK;
114
115  drop:
116         dev_kfree_skb(skb);
117         return NETDEV_TX_OK;
118 }
119
120
121
122 /**
123 @ingroup init_functions
124 Register other driver entry points with the kernel
125 */
126 static const struct net_device_ops bcmNetDevOps = {
127     .ndo_open           = bcm_open,
128     .ndo_stop           = bcm_close,
129     .ndo_get_stats      = bcm_get_stats,
130     .ndo_start_xmit     = bcm_transmit,
131     .ndo_change_mtu     = eth_change_mtu,
132     .ndo_set_mac_address = eth_mac_addr,
133     .ndo_validate_addr  = eth_validate_addr,
134     .ndo_select_queue   = bcm_select_queue,
135 };
136
137 static struct device_type wimax_type = {
138         .name   = "wimax",
139 };
140
141 static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
142 {
143         cmd->supported          = 0;
144         cmd->advertising        = 0;
145         cmd->speed              = SPEED_10000;
146         cmd->duplex             = DUPLEX_FULL;
147         cmd->port               = PORT_TP;
148         cmd->phy_address        = 0;
149         cmd->transceiver        = XCVR_INTERNAL;
150         cmd->autoneg            = AUTONEG_DISABLE;
151         cmd->maxtxpkt           = 0;
152         cmd->maxrxpkt           = 0;
153         return 0;
154 }
155
156 static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
157 {
158         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
159         PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter;
160         struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
161
162         strcpy(info->driver, DRV_NAME);
163         strcpy(info->version, DRV_VERSION);
164         snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u",
165                  Adapter->uiFlashLayoutMajorVersion,
166                  Adapter->uiFlashLayoutMinorVersion);
167
168         usb_make_path(udev, info->bus_info, sizeof(info->bus_info));
169 }
170
171 static u32 bcm_get_link(struct net_device *dev)
172 {
173         PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev);
174
175         return Adapter->LinkUpStatus;
176 }
177
178 static 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 };
183
184 int register_networkdev(PMINI_ADAPTER Adapter)
185 {
186         struct net_device *net = Adapter->dev;
187         int result;
188
189         net->netdev_ops = &bcmNetDevOps;
190         net->ethtool_ops = &bcm_ethtool_ops;
191         net->mtu          = MTU_SIZE; /* 1400 Bytes */
192         net->tx_queue_len = TX_QLEN;
193         net->flags |= IFF_NOARP;
194         net->flags &= ~(IFF_BROADCAST|IFF_MULTICAST);
195
196         netif_carrier_off(net);
197
198         SET_NETDEV_DEVTYPE(net, &wimax_type);
199
200         /* Read the MAC Address from EEPROM */
201         ReadMacAddressFromNVM(Adapter);
202
203         result = register_netdev(net);
204         if (result == 0)
205                 gblpnetdev = Adapter->dev = net;
206         else {
207                 Adapter->dev = NULL;
208                 free_netdev(net);
209         }
210
211         return result;
212 }
213
214 static int bcm_init(void)
215 {
216         printk(KERN_INFO "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
217         printk(KERN_INFO "%s\n", DRV_COPYRIGHT);
218
219         return InterfaceInitialize();
220 }
221
222
223 static void bcm_exit(void)
224 {
225         InterfaceExit();
226 }
227
228 module_init(bcm_init);
229 module_exit(bcm_exit);
230
231 MODULE_DESCRIPTION(DRV_DESCRIPTION);
232 MODULE_VERSION(DRV_VERSION);
233 MODULE_LICENSE ("GPL");
234