1#include "headers.h" 2 3struct net_device *gblpnetdev; 4 5static 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 29static 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 42static 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 60static 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 110Register other driver entry points with the kernel 111*/ 112static 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 122static struct device_type wimax_type = { 123 .name = "wimax", 124}; 125 126static 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 141static void bcm_get_drvinfo(struct net_device *dev, 142 struct ethtool_drvinfo *info) 143{ 144 PMINI_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 157static u32 bcm_get_link(struct net_device *dev) 158{ 159 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); 160 161 return Adapter->LinkUpStatus; 162} 163 164static u32 bcm_get_msglevel(struct net_device *dev) 165{ 166 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); 167 168 return Adapter->msg_enable; 169} 170 171static void bcm_set_msglevel(struct net_device *dev, u32 level) 172{ 173 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); 174 175 Adapter->msg_enable = level; 176} 177 178static 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 186int register_networkdev(PMINI_ADAPTER Adapter) 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 227void unregister_networkdev(PMINI_ADAPTER Adapter) 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} 240