⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nsmos.c

📁 NATIONAL公司DP83816芯片Linux下驱动
💻 C
📖 第 1 页 / 共 4 页
字号:

      // Stop Netstack from sending more pkts
      netif_stop_queue(netdev);

      // Reset Receive Engine - To get back pending fragments
      spin_lock_irq(&adapter->rxLock);
      MplReceiveReset(adapter->mplContext);
      spin_unlock_irq(&adapter->rxLock);

      // Reset Transmit Engine - To get back pending pkt
      spin_lock_irq(&adapter->txLock);
      MplTransmitReset(adapter->mplContext);
      spin_unlock_irq(&adapter->txLock);

#ifdef LINUX_POWER_DEBUG
      MplWolCfg(adapter->mplContext, NS_TRUE, adapter->wolModes);
#endif //NSM_DEBUG

      // Put device in LOW_POWER mode - Ask MPL to set PME for us
      status = MplPowerSetState(adapter->mplContext, 
                                    MPL_POWER_STATE_LOW, NS_TRUE);
   }

   // Detach our device from active list
   netif_device_detach(netdev);
   rtnl_unlock();
   return 0;
}

NS_SINT
NsmResume(struct pci_dev *pdev)
{
   struct net_device *netdev = pci_get_drvdata(pdev);
   NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
   MPL_STATUS status;
   NS_SINT ret;

   rtnl_lock();
   if (netif_device_present(netdev))
   {
      rtnl_unlock();
      return 0x0;
   }

   if (netif_running(netdev)) 
   {
      // Enable PCI device
      ret = pci_enable_device(pdev);

      // Put device in HIGH_POWER mode
      status = MplPowerSetState(adapter->mplContext, 
                                    MPL_POWER_STATE_HIGH, NS_TRUE);

      // Replenish MPL with Receive Buffers
      replenishTask((unsigned long)adapter);

      // Enable Interrupts
      MplInterruptEnable(adapter->mplContext);

      // Configure the Link - Done after Ints are enabled
      configLink(adapter);
   }

   // Attach our device to active list
   netif_device_attach(netdev);
   rtnl_unlock();
   return 0x0;
}
#endif

NS_VOID
NsmRemove(struct pci_dev *pdev)
{
   struct net_device *netdev;
   NSM_CONTEXT *adapter;

   NI(NsmRemove);

   netdev = pci_get_drvdata(pdev);

   // Adapter not found!
   if(netdev == NULL)
   {
      NSM_DBG(DBG_ERR,("Adapter Not Found! \n"));
      NO(NsmRemove);
      return;
   }

   // Get our private device struct
   adapter = (NSM_CONTEXT *) netdev->priv;

   // Unregister this Net device from the OS
   if (adapter->netdevReg == NS_TRUE)
   {
      unregister_netdev(netdev);
   }

   // MPL:UnInitialize the adapter
   if (adapter->mplContext != NULL) 
   {
      MplUnload(adapter->mplContext); 
   }

   // Free system resources
#ifdef NSM_IO_MAP
   if(adapter->regAddr != NULL) 
   {
      adapter->regAddr = NULL;
   }
#else
   if(adapter->regAddr != NULL) 
   {
      // First unmap the memory
      iounmap(adapter->regAddr);
      adapter->regAddr = NULL;
   }
#endif
   // Release the PCI address space
   pci_release_regions(pdev);

   // Free the Netdev struct and my NSM context struct
   kfree(netdev);

   // Decrement cards found
   NsmAdapterCnt--; 

   NO(NsmRemove);
   return;
}

NS_SINT
NsmOpen(struct net_device *netdev)
{
   NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;

   NI(NsmOpen);

   // Register Interrupt Service Routine
   if (request_irq(netdev->irq, &NsmIsr, SA_SHIRQ, DP_driverName, adapter)) 
   {
      NSM_DBG(DBG_ERR,("Failed to Get IRQ \n"));

      NO(NsmOpen);
      return -EAGAIN;
   }

   // Initialize SpinLocks
   spin_lock_init(&adapter->txLock);
   spin_lock_init(&adapter->rxLock);
   spin_lock_init(&adapter->linkLock);

   // Get Mpl Capabilities
   MplGetCaps(adapter->mplContext, &adapter->mplCaps);

   // Normal and Monitor mode : Cfg Mac, Link, RxFrags
   // Load only mode : Open only
   if (adapter->opMode != MPL_MODE_LOAD_ONLY)
   {
      // Configure the MAC
      if (configMac(adapter) == NS_FALSE)
      {
         NSM_DBG(DBG_ERR,("Config Mac Failed \n"));
         free_irq(netdev->irq, adapter);

         NO(NsmOpen);
         return -EAGAIN;
      }

      // Initialize link monitor tasklet
      tasklet_init(&adapter->linkMonTask, linkTask, (unsigned long) adapter);

      //Task Offloads Enables
      // Rx Filter (Multicast and Unicast Filtering)
      MplTaskFilterCfg(adapter->mplContext, NS_TRUE);

      // Allocate and setup MPL_FRAGs to hold Receive Buffers 
      //  These are wrapper structures used to post new buffers to MPL rx
      if (setupRxFrags(adapter) == NS_FALSE)
      {
         NSM_DBG(DBG_ERR,("Frag Setup Failed \n"));
         free_irq(netdev->irq, adapter);

         NO(NsmOpen);
         return -ENOMEM;
      }
   }

#ifdef NSM_DIAG_MODE
   // Initialize Diag Module
   if (adapter->opMode != MPL_MODE_NORMAL)
   {
      if (NsmDiagInitialize(adapter) != NS_STATUS_SUCCESS)
      {
            NSM_DBG(DBG_ERR,("Diag Setup Failed \n"));

            // Free the MPL Pkt Fragments 
            freeRxFrags(adapter);

            free_irq(netdev->irq, adapter);

            NO(NsmOpen);
            return -ENOMEM;
      }
   }
#endif //NSM_DIAG_MODE

   // Open the adapter for operations
   if (adapter->opMode != MPL_MODE_LOAD_ONLY)
   {
      // Replenish MPL with Receive Buffers
      replenishTask((unsigned long)adapter);

      // Open the MPL Adapter
      MplOpen(adapter->mplContext);

      // Configure the Link - Done after Ints are enabled
      configLink(adapter);
   }
   else
   {
      // Open the MPL Adapter - No other setups required here
      // We just assume the link is up - the diag app would need
      //  to ensure this is the case before doing any tx/rx
      MplOpen(adapter->mplContext);
      adapter->linkStatus = MPL_LINK_STATUS_UP;
   }


   // If the Link is not UP, notify Net Stack
   if ((adapter->linkStatus != MPL_LINK_STATUS_UP) ||
                (adapter->opMode != MPL_MODE_NORMAL))
   {
      netif_stop_queue(netdev);
   }

   NO(NsmOpen);
   return 0x0;
}


NS_SINT
NsmXmit(struct sk_buff *skb, struct net_device *netdev)
{
   NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;
   MPL_PKT mplPkt;
   MPL_PKT_FRAG mplFrag;
   MPL_STATUS status;

   NI(NsmXmit);
   
   // Test if the link is down
   if (adapter->linkStatus != MPL_LINK_STATUS_UP)
   {
      NSM_DBG(DBG_ERR,("Link Down \n"));
      netif_stop_queue(netdev);

      NO(NsmXmit);
      return -EAGAIN;
   }

   mplPkt.pNextPacket = NULL;
   mplPkt.fragCount = 0x01;

   // Set priority - FM: Map to higher level protocol?
   mplPkt.txOOB.pQueue = 1;

   // Prep MPL frag
   mplFrag.pNextFrag = NULL;
   mplFrag.fragSize  = skb->len;
   mplFrag.physAddr  = pci_map_single(adapter->pdev, 
                                       skb->data, skb->len, PCI_DMA_TODEVICE);
   mplFrag.pAddr     = skb->data;

   // Store in the physAddr of the skb in the private field
   *(NS_UINT *)skb->cb = mplFrag.physAddr;

   // Send Packet
   mplPkt.pFragHead = &mplFrag;
   mplPkt.packetSize  = skb->len;
   mplPkt.pNsmPrivate = skb; //Set Skb ptr as NSM private
   spin_lock_irq(&adapter->txLock);
   status = MplTransmit(adapter->mplContext, 0x01, &mplPkt);
   spin_unlock_irq(&adapter->txLock);

   // Check status
   if (status != NS_STATUS_SUCCESS)
   {
      if (mplPkt.packetStatus == NS_STATUS_RESOURCES)
      {
         // Stop the Net Stack
         netif_stop_queue(netdev);
         return -ENOMEM;
      }
      else
      {
         // Drop the pkt - Free the skb
         pci_unmap_single(adapter->pdev, mplFrag.physAddr, 
                              skb->len, PCI_DMA_TODEVICE);
         dev_kfree_skb(skb);
         adapter->netStats.tx_dropped++;
      }
   }

   NO(NsmXmit);
   return 0x0;
}

void
NsmSetMulti(struct net_device *netdev)
{   
   NSM_CONTEXT *adapter = netdev->priv;
   NS_UINT filterFlag, i;
   struct dev_mc_list *mcAddr;

   NI(NsmSetMulti);

   if (adapter->opMode != MPL_MODE_NORMAL)
   {
      return;
   }

   // Check if we need to go to Promiscuous Mode
   if (netdev->flags & IFF_PROMISC) 
   {
      filterFlag = MPL_RECEIVE_FILTER_PROMISCUOUS_MODE;
   }
   else 
   {
      // We always receive directed unicast and broadcast
      filterFlag = MPL_RECEIVE_FILTER_DIRECTED_UNICAST |
                     MPL_RECEIVE_FILTER_ACCEPTALL_BROADCAST;

      if (netdev->flags & IFF_ALLMULTI)
      {
         // All multicasts
         filterFlag |= MPL_RECEIVE_FILTER_ACCEPTALL_MCAST;
      }
      else
      {
         // Accept multicasts directed to our interest list
         filterFlag |= MPL_RECEIVE_FILTER_DIRECTED_MCAST;

         // Add multicast list to the device
         if(netdev->mc_count > 0x0)
         {
            // Clear the current MC list
            MplTaskFilterMcastClearList(adapter->mplContext);
 
            // Report the list to MPL
            mcAddr = netdev->mc_list;
            for (i = 0x0; i < netdev->mc_count; i++)
            {
               if (mcAddr != NULL)
               {
                  // Add the MC addr
                  MplTaskFilterMcastAddAddr(adapter->mplContext, 
                                              mcAddr->dmi_addr);

                  // Get the next MC addr
                  mcAddr = mcAddr->next;
               }
            }
         }
      }
   }
   
   MplReceiveSetFilter(adapter->mplContext, filterFlag);
   NO(NsmSetMulti);
   return;
}

struct net_device_stats *
NsmStats(struct net_device *netdev)
{
   NSM_CONTEXT *adapter = (NSM_CONTEXT *) netdev->priv;

   // NI(NsmStats);

   //FM: Update Stats from MPL
   // NO(NsmStats);
   return &adapter->netStats;
}

NS_SINT
NsmSetMac(struct net_device *netdev, void *p)
{
   struct sockaddr *mac = p;
   NSM_CONTEXT *adapter = netdev->priv;

   NI(NsmSetMac);
   memcpy(netdev->dev_addr, mac->sa_data, netdev->addr_len);

   MplSetMacAddress(adapter->mplContext, netdev->dev_addr);

   NO(NsmSetMac);
   return 0x0;
}

NS_SINT
NsmIoctl(struct net_device *netdev, struct ifreq *rq, NS_SINT cmd)
{
   NS_SINT ret = 0x0;
   NSM_CONTEXT *adapter = netdev->priv;
   struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;

   // NI(NsmIoctl);

   switch(cmd) 
   {
#ifdef NSM_DIAG_MODE
      // National's Integrity Tool
      case NS_APP_IOCTL_CODE: 
                          {
                             NS_UINT status;

                             // Handle the ioctl
                             status = NsmDiagIoctl(adapter, 
                                              (NS_VOID *) rq->ifr_data);
                             if (status != NS_STATUS_SUCCESS)
                             {
                                switch (status)
                                {
                                   case NS_STATUS_NOT_SUPPORTED: 
                                                          ret = -EOPNOTSUPP;
                                                          break;
                                   case NS_STATUS_INVALID_PARM: 
                                                          ret = -EINVAL;
                                                          break;
                                   case NS_STATUS_RESOURCES: 
                                                          ret = -ENOMEM;
                                                          break;
                                   default : 
                                                          ret = -EFAULT;
                                }
                             }
                             break;
                          }
#endif //NSM_DIAG_MODE

      // Other Linux Community Tools
      case SIOCETHTOOL    :
                             ret = -EOPNOTSUPP; //Soon to be supported
                             break; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -