linux/drivers/staging/bcm/Bcmnet.c
<<
>>
Prefs
   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