Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Bcmnet.c
Go to the documentation of this file.
1 #include "headers.h"
2 
4 
5 static INT bcm_open(struct net_device *dev)
6 {
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 {
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  struct bcm_mini_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 >=
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 
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,
142  struct ethtool_drvinfo *info)
143 {
144  struct bcm_mini_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 
157 static u32 bcm_get_link(struct net_device *dev)
158 {
159  struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
160 
161  return Adapter->LinkUpStatus;
162 }
163 
164 static u32 bcm_get_msglevel(struct net_device *dev)
165 {
166  struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
167 
168  return Adapter->msg_enable;
169 }
170 
171 static void bcm_set_msglevel(struct net_device *dev, u32 level)
172 {
173  struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
174 
175  Adapter->msg_enable = level;
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  .get_msglevel = bcm_get_msglevel,
183  .set_msglevel = bcm_set_msglevel,
184 };
185 
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; /* 1400 Bytes */
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  /* Read the MAC Address from EEPROM */
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 
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 }