1#include "headers.h" 2 3struct net_device *gblpnetdev; 4 5static INT bcm_open(struct net_device *dev) 6{ 7 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 8 9 if (ad->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(ad)) 16 pr_info(PFX "%s: enabling interface\n", dev->name); 17 18 if (ad->LinkUpStatus) { 19 if (netif_msg_link(ad)) 20 pr_info(PFX "%s: link up\n", dev->name); 21 22 netif_carrier_on(ad->dev); 23 netif_start_queue(ad->dev); 24 } 25 26 return 0; 27} 28 29static INT bcm_close(struct net_device *dev) 30{ 31 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 32 33 if (netif_msg_ifdown(ad)) 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 void *accel_priv, select_queue_fallback_t fallback) 44{ 45 return ClassifyPacket(netdev_priv(dev), skb); 46} 47 48/******************************************************************* 49* Function - bcm_transmit() 50* 51* Description - This is the main transmit function for our virtual 52* interface(eth0). It handles the ARP packets. It 53* clones this packet and then Queue it to a suitable 54* Queue. Then calls the transmit_packet(). 55* 56* Parameter - skb - Pointer to the socket buffer structure 57* dev - Pointer to the virtual net device structure 58* 59*********************************************************************/ 60 61static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) 62{ 63 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 64 u16 qindex = skb_get_queue_mapping(skb); 65 66 67 if (ad->device_removed || !ad->LinkUpStatus) 68 goto drop; 69 70 if (ad->TransferMode != IP_PACKET_ONLY_MODE) 71 goto drop; 72 73 if (INVALID_QUEUE_INDEX == qindex) 74 goto drop; 75 76 if (ad->PackInfo[qindex].uiCurrentPacketsOnHost >= 77 SF_MAX_ALLOWED_PACKETS_TO_BACKUP) 78 return NETDEV_TX_BUSY; 79 80 /* Now Enqueue the packet */ 81 if (netif_msg_tx_queued(ad)) 82 pr_info(PFX "%s: enqueueing packet to queue %d\n", 83 dev->name, qindex); 84 85 spin_lock(&ad->PackInfo[qindex].SFQueueLock); 86 ad->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; 87 ad->PackInfo[qindex].uiCurrentPacketsOnHost++; 88 89 *((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies; 90 ENQUEUEPACKET(ad->PackInfo[qindex].FirstTxQueue, 91 ad->PackInfo[qindex].LastTxQueue, skb); 92 atomic_inc(&ad->TotalPacketCount); 93 spin_unlock(&ad->PackInfo[qindex].SFQueueLock); 94 95 /* FIXME - this is racy and incorrect, replace with work queue */ 96 if (!atomic_read(&ad->TxPktAvail)) { 97 atomic_set(&ad->TxPktAvail, 1); 98 wake_up(&ad->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 109/** 110@ingroup init_functions 111Register other driver entry points with the kernel 112*/ 113static const struct net_device_ops bcmNetDevOps = { 114 .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, 121}; 122 123static struct device_type wimax_type = { 124 .name = "wimax", 125}; 126 127static 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 142static void bcm_get_drvinfo(struct net_device *dev, 143 struct ethtool_drvinfo *info) 144{ 145 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 146 struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; 147 struct usb_device *udev = interface_to_usbdev(intf_ad->interface); 148 149 strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); 150 strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 151 snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u", 152 ad->uiFlashLayoutMajorVersion, 153 ad->uiFlashLayoutMinorVersion); 154 155 usb_make_path(udev, info->bus_info, sizeof(info->bus_info)); 156} 157 158static u32 bcm_get_link(struct net_device *dev) 159{ 160 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 161 162 return ad->LinkUpStatus; 163} 164 165static u32 bcm_get_msglevel(struct net_device *dev) 166{ 167 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 168 169 return ad->msg_enable; 170} 171 172static void bcm_set_msglevel(struct net_device *dev, u32 level) 173{ 174 struct bcm_mini_adapter *ad = GET_BCM_ADAPTER(dev); 175 176 ad->msg_enable = level; 177} 178 179static const struct ethtool_ops bcm_ethtool_ops = { 180 .get_settings = bcm_get_settings, 181 .get_drvinfo = bcm_get_drvinfo, 182 .get_link = bcm_get_link, 183 .get_msglevel = bcm_get_msglevel, 184 .set_msglevel = bcm_set_msglevel, 185}; 186 187int register_networkdev(struct bcm_mini_adapter *ad) 188{ 189 struct net_device *net = ad->dev; 190 struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; 191 struct usb_interface *udev = intf_ad->interface; 192 struct usb_device *xdev = intf_ad->udev; 193 194 int result; 195 196 net->netdev_ops = &bcmNetDevOps; 197 net->ethtool_ops = &bcm_ethtool_ops; 198 net->mtu = MTU_SIZE; /* 1400 Bytes */ 199 net->tx_queue_len = TX_QLEN; 200 net->flags |= IFF_NOARP; 201 202 netif_carrier_off(net); 203 204 SET_NETDEV_DEVTYPE(net, &wimax_type); 205 206 /* Read the MAC Address from EEPROM */ 207 result = ReadMacAddressFromNVM(ad); 208 if (result != STATUS_SUCCESS) { 209 dev_err(&udev->dev, 210 PFX "Error in Reading the mac Address: %d", result); 211 return -EIO; 212 } 213 214 result = register_netdev(net); 215 if (result) 216 return result; 217 218 gblpnetdev = ad->dev; 219 220 if (netif_msg_probe(ad)) 221 dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n", 222 net->name, xdev->bus->bus_name, xdev->devpath, 223 net->dev_addr); 224 225 return 0; 226} 227 228void unregister_networkdev(struct bcm_mini_adapter *ad) 229{ 230 struct net_device *net = ad->dev; 231 struct bcm_interface_adapter *intf_ad = ad->pvInterfaceAdapter; 232 struct usb_interface *udev = intf_ad->interface; 233 struct usb_device *xdev = intf_ad->udev; 234 235 if (netif_msg_probe(ad)) 236 dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n", 237 net->name, xdev->bus->bus_name, xdev->devpath); 238 239 unregister_netdev(ad->dev); 240} 241