📄 mptlan.c
字号:
else pSimple->Address.High = 0; mpt_put_msg_frame (LanCtx, mpt_dev, mf); dev->trans_start = jiffies; dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n", IOC_AND_NETDEV_NAMES_s_s(dev), le32_to_cpu(pSimple->FlagsLength))); return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static inline voidmpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)/* * @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue */{ struct mpt_lan_priv *priv = dev->priv; if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { if (priority) { schedule_work(&priv->post_buckets_task); } else { schedule_delayed_work(&priv->post_buckets_task, 1); dioprintk((KERN_INFO MYNAM ": post_buckets queued on " "timer.\n")); } dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n", IOC_AND_NETDEV_NAMES_s_s(dev) )); }}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static inline intmpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb){ struct mpt_lan_priv *priv = dev->priv; skb->protocol = mpt_lan_type_trans(skb, dev); dioprintk((KERN_INFO MYNAM ": %s/%s: Incoming packet (%d bytes) " "delivered to upper level.\n", IOC_AND_NETDEV_NAMES_s_s(dev), skb->len)); priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; skb->dev = dev; netif_rx(skb); dioprintk((MYNAM "/receive_skb: %d buckets remaining\n", atomic_read(&priv->buckets_out))); if (atomic_read(&priv->buckets_out) < priv->bucketthresh) mpt_lan_wake_post_buckets_task(dev, 1); dioprintk((KERN_INFO MYNAM "/receive_post_reply: %d buckets " "remaining, %d received back since sod\n", atomic_read(&priv->buckets_out), priv->total_received)); return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*///static inline intstatic intmpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg){ struct mpt_lan_priv *priv = dev->priv; MPT_ADAPTER *mpt_dev = priv->mpt_dev; struct sk_buff *skb, *old_skb; unsigned long flags; u32 ctx, len; ctx = GET_LAN_BUCKET_CONTEXT(tmsg); skb = priv->RcvCtl[ctx].skb; len = GET_LAN_PACKET_LENGTH(tmsg); if (len < MPT_LAN_RX_COPYBREAK) { old_skb = skb; skb = (struct sk_buff *)dev_alloc_skb(len); if (!skb) { printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n", IOC_AND_NETDEV_NAMES_s_s(dev), __FILE__, __LINE__); return -ENOMEM; } pci_dma_sync_single_for_cpu(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); memcpy(skb_put(skb, len), old_skb->data, len); pci_dma_sync_single_for_device(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); goto out; } skb_put(skb, len); priv->RcvCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);out: spin_lock_irqsave(&priv->rxfidx_lock, flags); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); atomic_dec(&priv->buckets_out); priv->total_received++; return mpt_lan_receive_skb(dev, skb);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmpt_lan_receive_post_free(struct net_device *dev, LANReceivePostReply_t *pRecvRep){ struct mpt_lan_priv *priv = dev->priv; MPT_ADAPTER *mpt_dev = priv->mpt_dev; unsigned long flags; struct sk_buff *skb; u32 ctx; int count; int i; count = pRecvRep->NumberOfContexts;/**/ dlprintk((KERN_INFO MYNAM "/receive_post_reply: " "IOC returned %d buckets, freeing them...\n", count)); spin_lock_irqsave(&priv->rxfidx_lock, flags); for (i = 0; i < count; i++) { ctx = le32_to_cpu(pRecvRep->BucketContext[i]); skb = priv->RcvCtl[ctx].skb;// dlprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n",// IOC_AND_NETDEV_NAMES_s_s(dev)));// dlprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p",// priv, &(priv->buckets_out)));// dlprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n")); priv->RcvCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); dev_kfree_skb_any(skb); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; } spin_unlock_irqrestore(&priv->rxfidx_lock, flags); atomic_sub(count, &priv->buckets_out);// for (i = 0; i < priv->max_buckets_out; i++)// if (priv->RcvCtl[i].skb != NULL)// dlprintk((KERN_INFO MYNAM "@rpr: bucket %03x "// "is still out\n", i));/* dlprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n", count));*//**/ dlprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets "/**/ "remaining, %d received back since sod.\n",/**/ atomic_read(&priv->buckets_out), priv->total_received)); return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmpt_lan_receive_post_reply(struct net_device *dev, LANReceivePostReply_t *pRecvRep){ struct mpt_lan_priv *priv = dev->priv; MPT_ADAPTER *mpt_dev = priv->mpt_dev; struct sk_buff *skb, *old_skb; unsigned long flags; u32 len, ctx, offset; u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining); int count; int i, l; dioprintk((KERN_INFO MYNAM ": mpt_lan_receive_post_reply called\n")); dioprintk((KERN_INFO MYNAM ": receive_post_reply: IOCStatus: %04x\n", le16_to_cpu(pRecvRep->IOCStatus))); if ((le16_to_cpu(pRecvRep->IOCStatus) & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_LAN_CANCELED) return mpt_lan_receive_post_free(dev, pRecvRep); len = le32_to_cpu(pRecvRep->PacketLength); if (len == 0) { printk (KERN_ERR MYNAM ": %s/%s: ERROR - Got a non-TURBO " "ReceivePostReply w/ PacketLength zero!\n", IOC_AND_NETDEV_NAMES_s_s(dev)); printk (KERN_ERR MYNAM ": MsgFlags = %02x, IOCStatus = %04x\n", pRecvRep->MsgFlags, le16_to_cpu(pRecvRep->IOCStatus)); return -1; } ctx = le32_to_cpu(pRecvRep->BucketContext[0]); count = pRecvRep->NumberOfContexts; skb = priv->RcvCtl[ctx].skb; offset = le32_to_cpu(pRecvRep->PacketOffset);// if (offset != 0) {// printk (KERN_INFO MYNAM ": %s/%s: Got a ReceivePostReply "// "w/ PacketOffset %u\n",// IOC_AND_NETDEV_NAMES_s_s(dev),// offset);// } dioprintk((KERN_INFO MYNAM ": %s/%s: @rpr, offset = %d, len = %d\n", IOC_AND_NETDEV_NAMES_s_s(dev), offset, len)); if (count > 1) { int szrem = len;// dioprintk((KERN_INFO MYNAM ": %s/%s: Multiple buckets returned "// "for single packet, concatenating...\n",// IOC_AND_NETDEV_NAMES_s_s(dev))); skb = (struct sk_buff *)dev_alloc_skb(len); if (!skb) { printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n", IOC_AND_NETDEV_NAMES_s_s(dev), __FILE__, __LINE__); return -ENOMEM; } spin_lock_irqsave(&priv->rxfidx_lock, flags); for (i = 0; i < count; i++) { ctx = le32_to_cpu(pRecvRep->BucketContext[i]); old_skb = priv->RcvCtl[ctx].skb; l = priv->RcvCtl[ctx].len; if (szrem < l) l = szrem;// dioprintk((KERN_INFO MYNAM ": %s/%s: Buckets = %d, len = %u\n",// IOC_AND_NETDEV_NAMES_s_s(dev),// i, l)); pci_dma_sync_single_for_cpu(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); memcpy(skb_put(skb, l), old_skb->data, l); pci_dma_sync_single_for_device(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; szrem -= l; } spin_unlock_irqrestore(&priv->rxfidx_lock, flags); } else if (len < MPT_LAN_RX_COPYBREAK) { old_skb = skb; skb = (struct sk_buff *)dev_alloc_skb(len); if (!skb) { printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n", IOC_AND_NETDEV_NAMES_s_s(dev), __FILE__, __LINE__); return -ENOMEM; } pci_dma_sync_single_for_cpu(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); memcpy(skb_put(skb, len), old_skb->data, len); pci_dma_sync_single_for_device(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); spin_lock_irqsave(&priv->rxfidx_lock, flags); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); } else { spin_lock_irqsave(&priv->rxfidx_lock, flags); priv->RcvCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma, priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE); priv->RcvCtl[ctx].dma = 0; priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); skb_put(skb,len); } atomic_sub(count, &priv->buckets_out); priv->total_received += count; if (priv->mpt_rxfidx_tail >= MPT_LAN_MAX_BUCKETS_OUT) { printk (KERN_ERR MYNAM ": %s/%s: Yoohoo! mpt_rxfidx_tail = %d, " "MPT_LAN_MAX_BUCKETS_OUT = %d\n", IOC_AND_NETDEV_NAMES_s_s(dev), priv->mpt_rxfidx_tail, MPT_LAN_MAX_BUCKETS_OUT); panic("Damn it Jim! I'm a doctor, not a programmer! " "Oh, wait a sec, I am a programmer. " "And, who's Jim?!?!\n" "Arrgghh! We've done it again!\n"); } if (remaining == 0) printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! " "(priv->buckets_out = %d)\n", IOC_AND_NETDEV_NAMES_s_s(dev), atomic_read(&priv->buckets_out)); else if (remaining < 10) printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. " "(priv->buckets_out = %d)\n", IOC_AND_NETDEV_NAMES_s_s(dev), remaining, atomic_read(&priv->buckets_out)); if ((remaining < priv->bucketthresh) && ((atomic_read(&priv->buckets_out) - remaining) > MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH)) { printk (KERN_WARNING MYNAM " Mismatch between driver's " "buckets_out count and fw's BucketsRemaining " "count has crossed the threshold, issuing a " "LanReset to clear the fw's hashtable. You may " "want to check your /var/log/messages for \"CRC " "error\" event notifications.\n"); mpt_lan_reset(dev); mpt_lan_wake_post_buckets_task(dev, 0); } return mpt_lan_receive_skb(dev, skb);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*//* Simple SGE's only at the moment */static voidmpt_lan_post_receive_buckets(void *dev_id){ struct net_device *dev = dev_id; struct mpt_lan_priv *priv = dev->priv; MPT_ADAPTER *mpt_dev = priv->mpt_dev; MPT_FRAME_HDR *mf; LANReceivePostRequest_t *pRecvReq; SGETransaction32_t *pTrans; SGESimple64_t *pSimple; struct sk_buff *skb; dma_addr_t dma; u32 curr, buckets, count, max; u32 len = (dev->mtu + dev->hard_header_len + 4); unsigned long flags; int i; curr = atomic_read(&priv->buckets_out); buckets = (priv->max_buckets_out - curr); dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n", IOC_AND_NETDEV_NAMES_s_s(dev), __FUNCTION__, buckets, curr)); max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); while (buckets) { mf = mpt_get_msg_frame(LanCtx, mpt_dev); if (mf == NULL) { printk (KERN_ERR "%s: Unable to alloc request frame\n", __FUNCTION__); dioprintk((KERN_ERR "%s: %u buckets remaining\n", __FUNCTION__, buckets)); goto out; } pRecvReq = (LANReceivePostRequest_t *) mf; count = buckets; if (count > max) count = max; pRecvReq->Function = MPI_FUNCTION_LAN_RECEIVE; pRecvReq->ChainOffset = 0; pRecvReq->MsgFlags = 0; pRecvReq->PortNumber = priv->pnum; pTrans = (SGETransaction32_t *) pRecvReq->SG_List; pSimple = NULL; for (i = 0; i < count; i++) { int ctx; spin_lock_irqsave(&priv->rxfidx_lock, flags); if (priv->mpt_rxfidx_tail < 0) { printk (KERN_ERR "%s: Can't alloc context\n", __FUNCTION__); spin_unlock_irqrestore(&priv->rxfidx_lock,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -