blob: 8dfdd2732bdc329b3865c010d0afdb8e1e248337 [file] [log] [blame]
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07001#include "headers.h"
2
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07003struct net_device *gblpnetdev;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -07004
5static INT bcm_open(struct net_device *dev)
6{
Kevin McKinney29794602012-05-26 12:05:12 -04007 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Stephen Hemminger0ad008f2010-10-29 16:44:07 -07008
Lisa Nguyenf70c8a92013-10-28 01:36:19 -07009 if (Adapter->fw_download_done == false) {
Stephen Hemminger9ec44752010-11-01 12:18:36 -040010 pr_notice(PFX "%s: link up failed (download in progress)\n",
Vinay Sawal00b6fb22011-03-09 13:47:35 -080011 dev->name);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040012 return -EBUSY;
13 }
Stephen Hemminger46c37902010-11-01 10:16:29 -040014
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040015 if (netif_msg_ifup(Adapter))
Stephen Hemminger9ec44752010-11-01 12:18:36 -040016 pr_info(PFX "%s: enabling interface\n", dev->name);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040017
18 if (Adapter->LinkUpStatus) {
19 if (netif_msg_link(Adapter))
Stephen Hemminger9ec44752010-11-01 12:18:36 -040020 pr_info(PFX "%s: link up\n", dev->name);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040021
22 netif_carrier_on(Adapter->dev);
23 netif_start_queue(Adapter->dev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070024 }
25
Stephen Hemminger46c37902010-11-01 10:16:29 -040026 return 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070027}
28
29static INT bcm_close(struct net_device *dev)
30{
Kevin McKinney29794602012-05-26 12:05:12 -040031 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040032
33 if (netif_msg_ifdown(Adapter))
Stephen Hemminger9ec44752010-11-01 12:18:36 -040034 pr_info(PFX "%s: disabling interface\n", dev->name);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040035
36 netif_carrier_off(dev);
37 netif_stop_queue(dev);
38
Stephen Hemminger46c37902010-11-01 10:16:29 -040039 return 0;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -070040}
41
Jason Wangf663dd92014-01-10 16:18:26 +080042static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb,
43 void *accel_priv)
Stephen Hemminger93711052010-10-31 23:55:21 -040044{
45 return ClassifyPacket(netdev_priv(dev), skb);
46}
47
Stephen Hemminger93711052010-10-31 23:55:21 -040048/*******************************************************************
49* Function - bcm_transmit()
50*
51* Description - This is the main transmit function for our virtual
Stephen Hemminger46c37902010-11-01 10:16:29 -040052* interface(eth0). It handles the ARP packets. It
53* clones this packet and then Queue it to a suitable
Vinay Sawal00b6fb22011-03-09 13:47:35 -080054* Queue. Then calls the transmit_packet().
Stephen Hemminger93711052010-10-31 23:55:21 -040055*
56* Parameter - skb - Pointer to the socket buffer structure
Stephen Hemminger46c37902010-11-01 10:16:29 -040057* dev - Pointer to the virtual net device structure
Stephen Hemminger93711052010-10-31 23:55:21 -040058*
59*********************************************************************/
60
61static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev)
62{
Kevin McKinney29794602012-05-26 12:05:12 -040063 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Stephen Hemminger93711052010-10-31 23:55:21 -040064 u16 qindex = skb_get_queue_mapping(skb);
65
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040066
Stephen Hemminger93711052010-10-31 23:55:21 -040067 if (Adapter->device_removed || !Adapter->LinkUpStatus)
68 goto drop;
69
Stephen Hemminger46c37902010-11-01 10:16:29 -040070 if (Adapter->TransferMode != IP_PACKET_ONLY_MODE)
Stephen Hemminger93711052010-10-31 23:55:21 -040071 goto drop;
72
Stephen Hemminger46c37902010-11-01 10:16:29 -040073 if (INVALID_QUEUE_INDEX == qindex)
Stephen Hemminger93711052010-10-31 23:55:21 -040074 goto drop;
75
Stephen Hemminger46c37902010-11-01 10:16:29 -040076 if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >=
77 SF_MAX_ALLOWED_PACKETS_TO_BACKUP)
Stephen Hemminger93711052010-10-31 23:55:21 -040078 return NETDEV_TX_BUSY;
79
80 /* Now Enqueue the packet */
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040081 if (netif_msg_tx_queued(Adapter))
Stephen Hemminger9ec44752010-11-01 12:18:36 -040082 pr_info(PFX "%s: enqueueing packet to queue %d\n",
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -040083 dev->name, qindex);
Stephen Hemminger46c37902010-11-01 10:16:29 -040084
Stephen Hemminger93711052010-10-31 23:55:21 -040085 spin_lock(&Adapter->PackInfo[qindex].SFQueueLock);
86 Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len;
87 Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++;
88
Stephen Hemminger46c37902010-11-01 10:16:29 -040089 *((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies;
Stephen Hemminger93711052010-10-31 23:55:21 -040090 ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue,
91 Adapter->PackInfo[qindex].LastTxQueue, skb);
92 atomic_inc(&Adapter->TotalPacketCount);
93 spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock);
94
Stephen Hemminger93711052010-10-31 23:55:21 -040095 /* 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
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700109/**
110@ingroup init_functions
111Register other driver entry points with the kernel
112*/
Stephen Hemminger0ad008f2010-10-29 16:44:07 -0700113static const struct net_device_ops bcmNetDevOps = {
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800114 .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,
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700121};
Stephen Hemminger0ad008f2010-10-29 16:44:07 -0700122
123static struct device_type wimax_type = {
124 .name = "wimax",
125};
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700126
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700127static 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
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800142static void bcm_get_drvinfo(struct net_device *dev,
143 struct ethtool_drvinfo *info)
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700144{
Kevin McKinney29794602012-05-26 12:05:12 -0400145 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Ebru Akagunduz95a7a862013-10-07 18:09:59 +0300146 struct bcm_interface_adapter *psIntfAdapter =
147 Adapter->pvInterfaceAdapter;
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700148 struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
149
Jiri Pirko7826d432013-01-06 00:44:26 +0000150 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
151 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700152 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
159static u32 bcm_get_link(struct net_device *dev)
160{
Kevin McKinney29794602012-05-26 12:05:12 -0400161 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700162
163 return Adapter->LinkUpStatus;
164}
165
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800166static u32 bcm_get_msglevel(struct net_device *dev)
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -0400167{
Kevin McKinney29794602012-05-26 12:05:12 -0400168 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -0400169
170 return Adapter->msg_enable;
171}
172
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800173static void bcm_set_msglevel(struct net_device *dev, u32 level)
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -0400174{
Kevin McKinney29794602012-05-26 12:05:12 -0400175 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -0400176
177 Adapter->msg_enable = level;
178}
179
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700180static const struct ethtool_ops bcm_ethtool_ops = {
181 .get_settings = bcm_get_settings,
182 .get_drvinfo = bcm_get_drvinfo,
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800183 .get_link = bcm_get_link,
Stephen Hemminger4fd64dd2010-11-01 12:12:31 -0400184 .get_msglevel = bcm_get_msglevel,
185 .set_msglevel = bcm_set_msglevel,
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700186};
187
Kevin McKinney29794602012-05-26 12:05:12 -0400188int register_networkdev(struct bcm_mini_adapter *Adapter)
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700189{
Stephen Hemmingere614e282010-11-01 09:52:14 -0400190 struct net_device *net = Adapter->dev;
Kevin McKinneyd6861cf2012-11-01 23:42:21 -0400191 struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400192 struct usb_interface *udev = IntfAdapter->interface;
193 struct usb_device *xdev = IntfAdapter->udev;
194
Stephen Hemminger0ad008f2010-10-29 16:44:07 -0700195 int result;
196
Stephen Hemminger46c37902010-11-01 10:16:29 -0400197 net->netdev_ops = &bcmNetDevOps;
Stephen Hemmingerd21d6dde2010-10-29 17:12:37 -0700198 net->ethtool_ops = &bcm_ethtool_ops;
Stephen Hemminger46c37902010-11-01 10:16:29 -0400199 net->mtu = MTU_SIZE; /* 1400 Bytes */
Stephen Hemmingerd7affd02010-10-29 17:15:06 -0700200 net->tx_queue_len = TX_QLEN;
Stephen Hemminger74416982010-11-01 09:53:58 -0400201 net->flags |= IFF_NOARP;
Stephen Hemminger74416982010-11-01 09:53:58 -0400202
Stephen Hemminger2515ab62010-10-29 21:39:54 -0700203 netif_carrier_off(net);
Stephen Hemminger0ad008f2010-10-29 16:44:07 -0700204
Stephen Hemminger0ad008f2010-10-29 16:44:07 -0700205 SET_NETDEV_DEVTYPE(net, &wimax_type);
206
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700207 /* Read the MAC Address from EEPROM */
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400208 result = ReadMacAddressFromNVM(Adapter);
209 if (result != STATUS_SUCCESS) {
210 dev_err(&udev->dev,
211 PFX "Error in Reading the mac Address: %d", result);
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800212 return -EIO;
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700213 }
214
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400215 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
Kevin McKinney29794602012-05-26 12:05:12 -0400229void unregister_networkdev(struct bcm_mini_adapter *Adapter)
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400230{
231 struct net_device *net = Adapter->dev;
Kevin McKinneyd6861cf2012-11-01 23:42:21 -0400232 struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter;
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400233 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);
Vinay Sawal00b6fb22011-03-09 13:47:35 -0800239
Stephen Hemminger4ea4f7a2010-11-01 14:06:24 -0400240 unregister_netdev(Adapter->dev);
Stephen Hemmingerf8942e02010-09-08 14:46:36 -0700241}