diff options
Diffstat (limited to 'drivers/message/fusion/mptlan.c')
| -rw-r--r-- | drivers/message/fusion/mptlan.c | 214 |
1 files changed, 48 insertions, 166 deletions
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 7950fc678ed..cbe96072a6c 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -4,7 +4,7 @@ * For use with LSI Fibre Channel PCI chip/adapters * running LSI Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2007 LSI Corporation + * Copyright (c) 2000-2008 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * */ @@ -56,6 +56,8 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> +#include <linux/sched.h> +#include <linux/slab.h> #define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "mptlan" @@ -77,12 +79,6 @@ MODULE_VERSION(my_VERSION); * Fusion MPT LAN private structures */ -struct NAA_Hosed { - u16 NAA; - u8 ieee[FC_ALEN]; - struct NAA_Hosed *next; -}; - struct BufferControl { struct sk_buff *skb; dma_addr_t dma; @@ -112,7 +108,6 @@ struct mpt_lan_priv { u32 total_posted; u32 total_received; - struct net_device_stats stats; /* Per device statistics */ struct delayed_work post_buckets_task; struct net_device *dev; @@ -159,11 +154,6 @@ static u8 LanCtx = MPT_MAX_PROTOCOL_DRIVERS; static u32 max_buckets_out = 127; static u32 tx_max_out_p = 127 - 16; -#ifdef QLOGIC_NAA_WORKAROUND -static struct NAA_Hosed *mpt_bad_naa = NULL; -DEFINE_RWLOCK(bad_naa_lock); -#endif - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * lan_reply - Handle all data sent from the hardware. @@ -559,15 +549,6 @@ mpt_lan_close(struct net_device *dev) } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ -static struct net_device_stats * -mpt_lan_get_stats(struct net_device *dev) -{ - struct mpt_lan_priv *priv = netdev_priv(dev); - - return (struct net_device_stats *) &priv->stats; -} - -/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int mpt_lan_change_mtu(struct net_device *dev, int new_mtu) { @@ -605,12 +586,12 @@ mpt_lan_send_turbo(struct net_device *dev, u32 tmsg) ctx = GET_LAN_BUFFER_CONTEXT(tmsg); sent = priv->SendCtl[ctx].skb; - priv->stats.tx_packets++; - priv->stats.tx_bytes += sent->len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += sent->len; dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __FUNCTION__, sent)); + __func__, sent)); priv->SendCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, @@ -647,7 +628,7 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) switch (le16_to_cpu(pSendRep->IOCStatus) & MPI_IOCSTATUS_MASK) { case MPI_IOCSTATUS_SUCCESS: - priv->stats.tx_packets += count; + dev->stats.tx_packets += count; break; case MPI_IOCSTATUS_LAN_CANCELED: @@ -655,13 +636,13 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) break; case MPI_IOCSTATUS_INVALID_SGL: - priv->stats.tx_errors += count; + dev->stats.tx_errors += count; printk (KERN_ERR MYNAM ": %s/%s: ERROR - Invalid SGL sent to IOC!\n", IOC_AND_NETDEV_NAMES_s_s(dev)); goto out; default: - priv->stats.tx_errors += count; + dev->stats.tx_errors += count; break; } @@ -672,11 +653,11 @@ mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep) ctx = GET_LAN_BUFFER_CONTEXT(le32_to_cpu(*pContext)); sent = priv->SendCtl[ctx].skb; - priv->stats.tx_bytes += sent->len; + dev->stats.tx_bytes += sent->len; dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __FUNCTION__, sent)); + __func__, sent)); priv->SendCtl[ctx].skb = NULL; pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma, @@ -715,7 +696,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) u16 cur_naa = 0x1000; dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n", - __FUNCTION__, skb)); + __func__, skb)); spin_lock_irqsave(&priv->txfidx_lock, flags); if (priv->mpt_txfidx_tail < 0) { @@ -723,8 +704,8 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&priv->txfidx_lock, flags); printk (KERN_ERR "%s: no tx context available: %u\n", - __FUNCTION__, priv->mpt_txfidx_tail); - return 1; + __func__, priv->mpt_txfidx_tail); + return NETDEV_TX_BUSY; } mf = mpt_get_msg_frame(LanCtx, mpt_dev); @@ -733,8 +714,8 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&priv->txfidx_lock, flags); printk (KERN_ERR "%s: Unable to alloc request frame\n", - __FUNCTION__); - return 1; + __func__); + return NETDEV_TX_BUSY; } ctx = priv->mpt_txfidx[priv->mpt_txfidx_tail--]; @@ -780,30 +761,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) // ctx, skb, skb->data)); mac = skb_mac_header(skb); -#ifdef QLOGIC_NAA_WORKAROUND -{ - struct NAA_Hosed *nh; - - /* Munge the NAA for Tx packets to QLogic boards, which don't follow - RFC 2625. The longer I look at this, the more my opinion of Qlogic - drops. */ - read_lock_irq(&bad_naa_lock); - for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) { - if ((nh->ieee[0] == mac[0]) && - (nh->ieee[1] == mac[1]) && - (nh->ieee[2] == mac[2]) && - (nh->ieee[3] == mac[3]) && - (nh->ieee[4] == mac[4]) && - (nh->ieee[5] == mac[5])) { - cur_naa = nh->NAA; - dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value " - "= %04x.\n", cur_naa)); - break; - } - } - read_unlock_irq(&bad_naa_lock); -} -#endif pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | (mac[0] << 8) | @@ -840,7 +797,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) IOC_AND_NETDEV_NAMES_s_s(dev), le32_to_cpu(pSimple->FlagsLength))); - return 0; + return NETDEV_TX_OK; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -850,7 +807,7 @@ mpt_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; + struct mpt_lan_priv *priv = netdev_priv(dev); if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { if (priority) { @@ -869,7 +826,7 @@ mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority) static int mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb) { - struct mpt_lan_priv *priv = dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); skb->protocol = mpt_lan_type_trans(skb, dev); @@ -877,8 +834,8 @@ mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb) "delivered to upper level.\n", IOC_AND_NETDEV_NAMES_s_s(dev), skb->len)); - priv->stats.rx_bytes += skb->len; - priv->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; skb->dev = dev; netif_rx(skb); @@ -901,7 +858,7 @@ mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb) static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg) { - struct mpt_lan_priv *priv = dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; struct sk_buff *skb, *old_skb; unsigned long flags; @@ -956,7 +913,7 @@ static int mpt_lan_receive_post_free(struct net_device *dev, LANReceivePostReply_t *pRecvRep) { - struct mpt_lan_priv *priv = dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; unsigned long flags; struct sk_buff *skb; @@ -1011,7 +968,7 @@ static int mpt_lan_receive_post_reply(struct net_device *dev, LANReceivePostReply_t *pRecvRep) { - struct mpt_lan_priv *priv = dev->priv; + struct mpt_lan_priv *priv = netdev_priv(dev); MPT_ADAPTER *mpt_dev = priv->mpt_dev; struct sk_buff *skb, *old_skb; unsigned long flags; @@ -1208,7 +1165,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n", IOC_AND_NETDEV_NAMES_s_s(dev), - __FUNCTION__, buckets, curr)); + __func__, buckets, curr)); max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); @@ -1217,9 +1174,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) mf = mpt_get_msg_frame(LanCtx, mpt_dev); if (mf == NULL) { printk (KERN_ERR "%s: Unable to alloc request frame\n", - __FUNCTION__); + __func__); dioprintk((KERN_ERR "%s: %u buckets remaining\n", - __FUNCTION__, buckets)); + __func__, buckets)); goto out; } pRecvReq = (LANReceivePostRequest_t *) mf; @@ -1244,7 +1201,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) spin_lock_irqsave(&priv->rxfidx_lock, flags); if (priv->mpt_rxfidx_tail < 0) { printk (KERN_ERR "%s: Can't alloc context\n", - __FUNCTION__); + __func__); spin_unlock_irqrestore(&priv->rxfidx_lock, flags); break; @@ -1267,7 +1224,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) if (skb == NULL) { printk (KERN_WARNING MYNAM "/%s: Can't alloc skb\n", - __FUNCTION__); + __func__); priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx; spin_unlock_irqrestore(&priv->rxfidx_lock, flags); break; @@ -1305,7 +1262,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) if (pSimple == NULL) { /**/ printk (KERN_WARNING MYNAM "/%s: No buckets posted\n", -/**/ __FUNCTION__); +/**/ __func__); mpt_free_msg_frame(mpt_dev, mf); goto out; } @@ -1329,9 +1286,9 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) out: dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n", - __FUNCTION__, buckets, atomic_read(&priv->buckets_out))); + __func__, buckets, atomic_read(&priv->buckets_out))); dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n", - __FUNCTION__, priv->total_posted, priv->total_received)); + __func__, priv->total_posted, priv->total_received)); clear_bit(0, &priv->post_buckets_active); } @@ -1343,6 +1300,14 @@ mpt_lan_post_receive_buckets_work(struct work_struct *work) post_buckets_task.work)); } +static const struct net_device_ops mpt_netdev_ops = { + .ndo_open = mpt_lan_open, + .ndo_stop = mpt_lan_close, + .ndo_start_xmit = mpt_lan_sdu_send, + .ndo_change_mtu = mpt_lan_change_mtu, + .ndo_tx_timeout = mpt_lan_tx_timeout, +}; + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static struct net_device * mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) @@ -1407,15 +1372,7 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) priv->tx_max_out = (tx_max_out_p <= MPT_TX_MAX_OUT_LIM) ? tx_max_out_p : MPT_TX_MAX_OUT_LIM; - dev->open = mpt_lan_open; - dev->stop = mpt_lan_close; - dev->get_stats = mpt_lan_get_stats; - dev->set_multicast_list = NULL; - dev->change_mtu = mpt_lan_change_mtu; - dev->hard_start_xmit = mpt_lan_sdu_send; - -/* Not in 2.3.42. Need 2.3.45+ */ - dev->tx_timeout = mpt_lan_tx_timeout; + dev->netdev_ops = &mpt_netdev_ops; dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT; dlprintk((KERN_INFO MYNAM ": Finished registering dev " @@ -1462,11 +1419,9 @@ mptlan_probe(struct pci_dev *pdev, const struct pci_device_id *id) printk(KERN_INFO MYNAM ": %s: Fusion MPT LAN device " "registered as '%s'\n", ioc->name, dev->name); printk(KERN_INFO MYNAM ": %s/%s: " - "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", + "LanAddr = %pM\n", IOC_AND_NETDEV_NAMES_s_s(dev), - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5]); + dev->dev_addr); ioc->netdev = dev; @@ -1497,7 +1452,9 @@ static int __init mpt_lan_init (void) { show_mptmod_ver(LANAME, LANVER); - if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) { + LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER, + "lan_reply"); + if (LanCtx <= 0) { printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n"); return -EBUSY; } @@ -1551,9 +1508,8 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) printk (KERN_WARNING MYNAM ": %s: WARNING - Broadcast swap F/W bug detected!\n", NETDEV_PTR_TO_IOC_NAME_s(dev)); - printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", - fch->saddr[0], fch->saddr[1], fch->saddr[2], - fch->saddr[3], fch->saddr[4], fch->saddr[5]); + printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %pM\n", + fch->saddr); } if (*fch->daddr & 1) { @@ -1572,80 +1528,6 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) fcllc = (struct fcllc *)skb->data; -#ifdef QLOGIC_NAA_WORKAROUND -{ - u16 source_naa = fch->stype, found = 0; - - /* Workaround for QLogic not following RFC 2625 in regards to the NAA - value. */ - - if ((source_naa & 0xF000) == 0) - source_naa = swab16(source_naa); - - if (fcllc->ethertype == htons(ETH_P_ARP)) - dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of " - "%04x.\n", source_naa)); - - if ((fcllc->ethertype == htons(ETH_P_ARP)) && - ((source_naa >> 12) != MPT_LAN_NAA_RFC2625)){ - struct NAA_Hosed *nh, *prevnh; - int i; - - dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from " - "system with non-RFC 2625 NAA value (%04x).\n", - source_naa)); - - write_lock_irq(&bad_naa_lock); - for (prevnh = nh = mpt_bad_naa; nh != NULL; - prevnh=nh, nh=nh->next) { - if ((nh->ieee[0] == fch->saddr[0]) && - (nh->ieee[1] == fch->saddr[1]) && - (nh->ieee[2] == fch->saddr[2]) && - (nh->ieee[3] == fch->saddr[3]) && - (nh->ieee[4] == fch->saddr[4]) && - (nh->ieee[5] == fch->saddr[5])) { - found = 1; - dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re" - "q/Rep w/ bad NAA from system already" - " in DB.\n")); - break; - } - } - - if ((!found) && (nh == NULL)) { - - nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL); - dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/" - " bad NAA from system not yet in DB.\n")); - - if (nh != NULL) { - nh->next = NULL; - if (!mpt_bad_naa) - mpt_bad_naa = nh; - if (prevnh) - prevnh->next = nh; - - nh->NAA = source_naa; /* Set the S_NAA value. */ - for (i = 0; i < FC_ALEN; i++) - nh->ieee[i] = fch->saddr[i]; - dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:" - "%02x:%02x with non-compliant S_NAA value.\n", - fch->saddr[0], fch->saddr[1], fch->saddr[2], - fch->saddr[3], fch->saddr[4],fch->saddr[5])); - } else { - printk (KERN_ERR "mptlan/type_trans: Unable to" - " kmalloc a NAA_Hosed struct.\n"); - } - } else if (!found) { - printk (KERN_ERR "mptlan/type_trans: found not" - " set, but nh isn't null. Evil " - "funkiness abounds.\n"); - } - write_unlock_irq(&bad_naa_lock); - } -} -#endif - /* Strip the SNAP header from ARP packets since we don't * pass them through to the 802.2/SNAP layers. */ |
