You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
RDMA: Update workqueue usage
RDMA/nes: Fix incorrect SFP+ link status detection on driver init
RDMA/nes: Fix SFP+ link down detection issue with switch port disable
RDMA/nes: Generate IB_EVENT_PORT_ERR/PORT_ACTIVE events
RDMA/nes: Fix bonding on iw_nes
IB/srp: Test only once whether iu allocation succeeded
IB/mlx4: Handle protocol field in multicast table
RDMA: Use vzalloc() to replace vmalloc()+memset(0)
mlx4_{core, ib, en}: Fix driver when sizeof (phys_addr_t) > sizeof (long)
IB/mthca: Fix driver when sizeof (phys_addr_t) > sizeof (long)
This commit is contained in:
@@ -308,7 +308,7 @@ static void ib_cache_event(struct ib_event_handler *handler,
|
||||
INIT_WORK(&work->work, ib_cache_task);
|
||||
work->device = event->device;
|
||||
work->port_num = event->element.port_num;
|
||||
schedule_work(&work->work);
|
||||
queue_work(ib_wq, &work->work);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,7 +368,7 @@ static void ib_cache_cleanup_one(struct ib_device *device)
|
||||
int p;
|
||||
|
||||
ib_unregister_event_handler(&device->cache.event_handler);
|
||||
flush_scheduled_work();
|
||||
flush_workqueue(ib_wq);
|
||||
|
||||
for (p = 0; p <= end_port(device) - start_port(device); ++p) {
|
||||
kfree(device->cache.pkey_cache[p]);
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "core_priv.h"
|
||||
|
||||
@@ -52,6 +51,9 @@ struct ib_client_data {
|
||||
void * data;
|
||||
};
|
||||
|
||||
struct workqueue_struct *ib_wq;
|
||||
EXPORT_SYMBOL_GPL(ib_wq);
|
||||
|
||||
static LIST_HEAD(device_list);
|
||||
static LIST_HEAD(client_list);
|
||||
|
||||
@@ -718,6 +720,10 @@ static int __init ib_core_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ib_wq = alloc_workqueue("infiniband", 0, 0);
|
||||
if (!ib_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = ib_sysfs_setup();
|
||||
if (ret)
|
||||
printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
|
||||
@@ -726,6 +732,7 @@ static int __init ib_core_init(void)
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "Couldn't set up InfiniBand P_Key/GID cache\n");
|
||||
ib_sysfs_cleanup();
|
||||
destroy_workqueue(ib_wq);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -736,7 +743,7 @@ static void __exit ib_core_cleanup(void)
|
||||
ib_cache_cleanup();
|
||||
ib_sysfs_cleanup();
|
||||
/* Make sure that any pending umem accounting work is done. */
|
||||
flush_scheduled_work();
|
||||
destroy_workqueue(ib_wq);
|
||||
}
|
||||
|
||||
module_init(ib_core_init);
|
||||
|
||||
@@ -425,7 +425,7 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event
|
||||
port->sm_ah = NULL;
|
||||
spin_unlock_irqrestore(&port->ah_lock, flags);
|
||||
|
||||
schedule_work(&sa_dev->port[event->element.port_num -
|
||||
queue_work(ib_wq, &sa_dev->port[event->element.port_num -
|
||||
sa_dev->start_port].update_task);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ void ib_umem_release(struct ib_umem *umem)
|
||||
umem->mm = mm;
|
||||
umem->diff = diff;
|
||||
|
||||
schedule_work(&umem->work);
|
||||
queue_work(ib_wq, &umem->work);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -459,13 +459,12 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev)
|
||||
IB_DEVICE_MEM_WINDOW);
|
||||
|
||||
/* Allocate the qptr_array */
|
||||
c2dev->qptr_array = vmalloc(C2_MAX_CQS * sizeof(void *));
|
||||
c2dev->qptr_array = vzalloc(C2_MAX_CQS * sizeof(void *));
|
||||
if (!c2dev->qptr_array) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Inialize the qptr_array */
|
||||
memset(c2dev->qptr_array, 0, C2_MAX_CQS * sizeof(void *));
|
||||
/* Initialize the qptr_array */
|
||||
c2dev->qptr_array[0] = (void *) &c2dev->req_vq;
|
||||
c2dev->qptr_array[1] = (void *) &c2dev->rep_vq;
|
||||
c2dev->qptr_array[2] = (void *) &c2dev->aeq;
|
||||
|
||||
@@ -222,15 +222,14 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
|
||||
queue->small_page = NULL;
|
||||
|
||||
/* allocate queue page pointers */
|
||||
queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL);
|
||||
queue->queue_pages = kzalloc(nr_of_pages * sizeof(void *), GFP_KERNEL);
|
||||
if (!queue->queue_pages) {
|
||||
queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
|
||||
queue->queue_pages = vzalloc(nr_of_pages * sizeof(void *));
|
||||
if (!queue->queue_pages) {
|
||||
ehca_gen_err("Couldn't allocate queue page list");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
|
||||
|
||||
/* allocate actual queue pages */
|
||||
if (is_small) {
|
||||
|
||||
@@ -199,12 +199,11 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dd = vmalloc(sizeof(*dd));
|
||||
dd = vzalloc(sizeof(*dd));
|
||||
if (!dd) {
|
||||
dd = ERR_PTR(-ENOMEM);
|
||||
goto bail;
|
||||
}
|
||||
memset(dd, 0, sizeof(*dd));
|
||||
dd->ipath_unit = -1;
|
||||
|
||||
spin_lock_irqsave(&ipath_devs_lock, flags);
|
||||
@@ -756,7 +755,7 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev)
|
||||
*/
|
||||
ipath_shutdown_device(dd);
|
||||
|
||||
flush_scheduled_work();
|
||||
flush_workqueue(ib_wq);
|
||||
|
||||
if (dd->verbs_dev)
|
||||
ipath_unregister_ib_device(dd->verbs_dev);
|
||||
|
||||
@@ -1530,7 +1530,7 @@ static int init_subports(struct ipath_devdata *dd,
|
||||
}
|
||||
|
||||
num_subports = uinfo->spu_subport_cnt;
|
||||
pd->subport_uregbase = vmalloc(PAGE_SIZE * num_subports);
|
||||
pd->subport_uregbase = vzalloc(PAGE_SIZE * num_subports);
|
||||
if (!pd->subport_uregbase) {
|
||||
ret = -ENOMEM;
|
||||
goto bail;
|
||||
@@ -1538,13 +1538,13 @@ static int init_subports(struct ipath_devdata *dd,
|
||||
/* Note: pd->port_rcvhdrq_size isn't initialized yet. */
|
||||
size = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize *
|
||||
sizeof(u32), PAGE_SIZE) * num_subports;
|
||||
pd->subport_rcvhdr_base = vmalloc(size);
|
||||
pd->subport_rcvhdr_base = vzalloc(size);
|
||||
if (!pd->subport_rcvhdr_base) {
|
||||
ret = -ENOMEM;
|
||||
goto bail_ureg;
|
||||
}
|
||||
|
||||
pd->subport_rcvegrbuf = vmalloc(pd->port_rcvegrbuf_chunks *
|
||||
pd->subport_rcvegrbuf = vzalloc(pd->port_rcvegrbuf_chunks *
|
||||
pd->port_rcvegrbuf_size *
|
||||
num_subports);
|
||||
if (!pd->subport_rcvegrbuf) {
|
||||
@@ -1556,11 +1556,6 @@ static int init_subports(struct ipath_devdata *dd,
|
||||
pd->port_subport_id = uinfo->spu_subport_id;
|
||||
pd->active_slaves = 1;
|
||||
set_bit(IPATH_PORT_MASTER_UNINIT, &pd->port_flag);
|
||||
memset(pd->subport_uregbase, 0, PAGE_SIZE * num_subports);
|
||||
memset(pd->subport_rcvhdr_base, 0, size);
|
||||
memset(pd->subport_rcvegrbuf, 0, pd->port_rcvegrbuf_chunks *
|
||||
pd->port_rcvegrbuf_size *
|
||||
num_subports);
|
||||
goto bail;
|
||||
|
||||
bail_rhdr:
|
||||
|
||||
@@ -442,7 +442,7 @@ static void init_shadow_tids(struct ipath_devdata *dd)
|
||||
struct page **pages;
|
||||
dma_addr_t *addrs;
|
||||
|
||||
pages = vmalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
|
||||
pages = vzalloc(dd->ipath_cfgports * dd->ipath_rcvtidcnt *
|
||||
sizeof(struct page *));
|
||||
if (!pages) {
|
||||
ipath_dev_err(dd, "failed to allocate shadow page * "
|
||||
@@ -461,9 +461,6 @@ static void init_shadow_tids(struct ipath_devdata *dd)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(pages, 0, dd->ipath_cfgports * dd->ipath_rcvtidcnt *
|
||||
sizeof(struct page *));
|
||||
|
||||
dd->ipath_pageshadow = pages;
|
||||
dd->ipath_physshadow = addrs;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ void ipath_release_user_pages_on_close(struct page **p, size_t num_pages)
|
||||
work->mm = mm;
|
||||
work->num_pages = num_pages;
|
||||
|
||||
schedule_work(&work->work);
|
||||
queue_work(ib_wq, &work->work);
|
||||
return;
|
||||
|
||||
bail_mm:
|
||||
|
||||
@@ -623,8 +623,9 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
|
||||
struct mlx4_ib_qp *mqp = to_mqp(ibqp);
|
||||
|
||||
err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, !!(mqp->flags &
|
||||
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK));
|
||||
err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw,
|
||||
!!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
|
||||
MLX4_PROTOCOL_IB);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -635,7 +636,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
return 0;
|
||||
|
||||
err_add:
|
||||
mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw);
|
||||
mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -665,7 +666,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
struct mlx4_ib_gid_entry *ge;
|
||||
|
||||
err = mlx4_multicast_detach(mdev->dev,
|
||||
&mqp->mqp, gid->raw);
|
||||
&mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1005,7 +1006,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
|
||||
if (mlx4_uar_alloc(dev, &ibdev->priv_uar))
|
||||
goto err_pd;
|
||||
|
||||
ibdev->uar_map = ioremap(ibdev->priv_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
|
||||
ibdev->uar_map = ioremap((phys_addr_t) ibdev->priv_uar.pfn << PAGE_SHIFT,
|
||||
PAGE_SIZE);
|
||||
if (!ibdev->uar_map)
|
||||
goto err_uar;
|
||||
MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock);
|
||||
|
||||
@@ -146,7 +146,7 @@ static void poll_catas(unsigned long dev_ptr)
|
||||
|
||||
void mthca_start_catas_poll(struct mthca_dev *dev)
|
||||
{
|
||||
unsigned long addr;
|
||||
phys_addr_t addr;
|
||||
|
||||
init_timer(&dev->catas_err.timer);
|
||||
dev->catas_err.map = NULL;
|
||||
@@ -158,7 +158,8 @@ void mthca_start_catas_poll(struct mthca_dev *dev)
|
||||
dev->catas_err.map = ioremap(addr, dev->catas_err.size * 4);
|
||||
if (!dev->catas_err.map) {
|
||||
mthca_warn(dev, "couldn't map catastrophic error region "
|
||||
"at 0x%lx/0x%x\n", addr, dev->catas_err.size * 4);
|
||||
"at 0x%llx/0x%x\n", (unsigned long long) addr,
|
||||
dev->catas_err.size * 4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -713,7 +713,7 @@ int mthca_RUN_FW(struct mthca_dev *dev, u8 *status)
|
||||
|
||||
static void mthca_setup_cmd_doorbells(struct mthca_dev *dev, u64 base)
|
||||
{
|
||||
unsigned long addr;
|
||||
phys_addr_t addr;
|
||||
u16 max_off = 0;
|
||||
int i;
|
||||
|
||||
|
||||
@@ -653,7 +653,7 @@ static int mthca_map_reg(struct mthca_dev *dev,
|
||||
unsigned long offset, unsigned long size,
|
||||
void __iomem **map)
|
||||
{
|
||||
unsigned long base = pci_resource_start(dev->pdev, 0);
|
||||
phys_addr_t base = pci_resource_start(dev->pdev, 0);
|
||||
|
||||
*map = ioremap(base + offset, size);
|
||||
if (!*map)
|
||||
|
||||
@@ -790,7 +790,7 @@ static int mthca_setup_hca(struct mthca_dev *dev)
|
||||
goto err_uar_table_free;
|
||||
}
|
||||
|
||||
dev->kar = ioremap(dev->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
|
||||
dev->kar = ioremap((phys_addr_t) dev->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE);
|
||||
if (!dev->kar) {
|
||||
mthca_err(dev, "Couldn't map kernel access region, "
|
||||
"aborting.\n");
|
||||
|
||||
@@ -853,7 +853,7 @@ void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr)
|
||||
|
||||
int mthca_init_mr_table(struct mthca_dev *dev)
|
||||
{
|
||||
unsigned long addr;
|
||||
phys_addr_t addr;
|
||||
int mpts, mtts, err, i;
|
||||
|
||||
err = mthca_alloc_init(&dev->mr_table.mpt_alloc,
|
||||
|
||||
@@ -144,6 +144,7 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
|
||||
struct nes_device *nesdev;
|
||||
struct net_device *netdev;
|
||||
struct nes_vnic *nesvnic;
|
||||
unsigned int is_bonded;
|
||||
|
||||
nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n",
|
||||
&ifa->ifa_address, &ifa->ifa_mask);
|
||||
@@ -152,7 +153,8 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
|
||||
nesdev, nesdev->netdev[0]->name);
|
||||
netdev = nesdev->netdev[0];
|
||||
nesvnic = netdev_priv(netdev);
|
||||
if (netdev == event_netdev) {
|
||||
is_bonded = (netdev->master == event_netdev);
|
||||
if ((netdev == event_netdev) || is_bonded) {
|
||||
if (nesvnic->rdma_enabled == 0) {
|
||||
nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since"
|
||||
" RDMA is not enabled.\n",
|
||||
@@ -169,7 +171,10 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
|
||||
nes_manage_arp_cache(netdev, netdev->dev_addr,
|
||||
ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE);
|
||||
nesvnic->local_ipaddr = 0;
|
||||
return NOTIFY_OK;
|
||||
if (is_bonded)
|
||||
continue;
|
||||
else
|
||||
return NOTIFY_OK;
|
||||
break;
|
||||
case NETDEV_UP:
|
||||
nes_debug(NES_DBG_NETDEV, "event:UP\n");
|
||||
@@ -178,15 +183,24 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
|
||||
nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n");
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
/* fall through */
|
||||
case NETDEV_CHANGEADDR:
|
||||
/* Add the address to the IP table */
|
||||
nesvnic->local_ipaddr = ifa->ifa_address;
|
||||
if (netdev->master)
|
||||
nesvnic->local_ipaddr =
|
||||
((struct in_device *)netdev->master->ip_ptr)->ifa_list->ifa_address;
|
||||
else
|
||||
nesvnic->local_ipaddr = ifa->ifa_address;
|
||||
|
||||
nes_write_indexed(nesdev,
|
||||
NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)),
|
||||
ntohl(ifa->ifa_address));
|
||||
ntohl(nesvnic->local_ipaddr));
|
||||
nes_manage_arp_cache(netdev, netdev->dev_addr,
|
||||
ntohl(nesvnic->local_ipaddr), NES_ARP_ADD);
|
||||
return NOTIFY_OK;
|
||||
if (is_bonded)
|
||||
continue;
|
||||
else
|
||||
return NOTIFY_OK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -660,6 +674,8 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
|
||||
}
|
||||
nes_notifiers_registered++;
|
||||
|
||||
INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status);
|
||||
|
||||
/* Initialize network devices */
|
||||
if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL)
|
||||
goto bail7;
|
||||
@@ -742,6 +758,7 @@ static void __devexit nes_remove(struct pci_dev *pcidev)
|
||||
struct nes_device *nesdev = pci_get_drvdata(pcidev);
|
||||
struct net_device *netdev;
|
||||
int netdev_index = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (nesdev->netdev_count) {
|
||||
netdev = nesdev->netdev[netdev_index];
|
||||
@@ -768,6 +785,14 @@ static void __devexit nes_remove(struct pci_dev *pcidev)
|
||||
free_irq(pcidev->irq, nesdev);
|
||||
tasklet_kill(&nesdev->dpc_tasklet);
|
||||
|
||||
spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags);
|
||||
if (nesdev->link_recheck) {
|
||||
spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
|
||||
cancel_delayed_work_sync(&nesdev->work);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags);
|
||||
}
|
||||
|
||||
/* Deallocate the Adapter Structure */
|
||||
nes_destroy_adapter(nesdev->nesadapter);
|
||||
|
||||
|
||||
@@ -268,6 +268,9 @@ struct nes_device {
|
||||
u8 napi_isr_ran;
|
||||
u8 disable_rx_flow_control;
|
||||
u8 disable_tx_flow_control;
|
||||
|
||||
struct delayed_work work;
|
||||
u8 link_recheck;
|
||||
};
|
||||
|
||||
|
||||
@@ -507,6 +510,7 @@ void nes_nic_ce_handler(struct nes_device *, struct nes_hw_nic_cq *);
|
||||
void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *);
|
||||
int nes_destroy_cqp(struct nes_device *);
|
||||
int nes_nic_cm_xmit(struct sk_buff *, struct net_device *);
|
||||
void nes_recheck_link_status(struct work_struct *work);
|
||||
|
||||
/* nes_nic.c */
|
||||
struct net_device *nes_netdev_init(struct nes_device *, void __iomem *);
|
||||
|
||||
@@ -1107,6 +1107,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
|
||||
struct flowi fl;
|
||||
struct neighbour *neigh;
|
||||
int rc = arpindex;
|
||||
struct net_device *netdev;
|
||||
struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
|
||||
|
||||
memset(&fl, 0, sizeof fl);
|
||||
@@ -1117,7 +1118,12 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
|
||||
return rc;
|
||||
}
|
||||
|
||||
neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev);
|
||||
if (nesvnic->netdev->master)
|
||||
netdev = nesvnic->netdev->master;
|
||||
else
|
||||
netdev = nesvnic->netdev;
|
||||
|
||||
neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev);
|
||||
if (neigh) {
|
||||
if (neigh->nud_state & NUD_VALID) {
|
||||
nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
|
||||
|
||||
@@ -2608,6 +2608,13 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
|
||||
netif_start_queue(nesvnic->netdev);
|
||||
nesvnic->linkup = 1;
|
||||
netif_carrier_on(nesvnic->netdev);
|
||||
|
||||
spin_lock(&nesvnic->port_ibevent_lock);
|
||||
if (nesdev->iw_status == 0) {
|
||||
nesdev->iw_status = 1;
|
||||
nes_port_ibevent(nesvnic);
|
||||
}
|
||||
spin_unlock(&nesvnic->port_ibevent_lock);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2633,9 +2640,23 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
|
||||
netif_stop_queue(nesvnic->netdev);
|
||||
nesvnic->linkup = 0;
|
||||
netif_carrier_off(nesvnic->netdev);
|
||||
|
||||
spin_lock(&nesvnic->port_ibevent_lock);
|
||||
if (nesdev->iw_status == 1) {
|
||||
nesdev->iw_status = 0;
|
||||
nes_port_ibevent(nesvnic);
|
||||
}
|
||||
spin_unlock(&nesvnic->port_ibevent_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_SFP_D) {
|
||||
if (nesdev->link_recheck)
|
||||
cancel_delayed_work(&nesdev->work);
|
||||
nesdev->link_recheck = 1;
|
||||
schedule_delayed_work(&nesdev->work,
|
||||
NES_LINK_RECHECK_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
|
||||
@@ -2643,6 +2664,80 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
|
||||
nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE;
|
||||
}
|
||||
|
||||
void nes_recheck_link_status(struct work_struct *work)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct nes_device *nesdev = container_of(work, struct nes_device, work.work);
|
||||
struct nes_adapter *nesadapter = nesdev->nesadapter;
|
||||
struct nes_vnic *nesvnic;
|
||||
u32 mac_index = nesdev->mac_index;
|
||||
u16 phy_data;
|
||||
u16 temp_phy_data;
|
||||
|
||||
spin_lock_irqsave(&nesadapter->phy_lock, flags);
|
||||
|
||||
/* check link status */
|
||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003);
|
||||
temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||
|
||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
|
||||
nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||
nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021);
|
||||
phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL);
|
||||
|
||||
phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0;
|
||||
|
||||
nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n",
|
||||
__func__, phy_data,
|
||||
nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP");
|
||||
|
||||
if (phy_data & 0x0004) {
|
||||
nesadapter->mac_link_down[mac_index] = 0;
|
||||
list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
|
||||
if (nesvnic->linkup == 0) {
|
||||
printk(PFX "The Link is now up for port %s, netdev %p.\n",
|
||||
nesvnic->netdev->name, nesvnic->netdev);
|
||||
if (netif_queue_stopped(nesvnic->netdev))
|
||||
netif_start_queue(nesvnic->netdev);
|
||||
nesvnic->linkup = 1;
|
||||
netif_carrier_on(nesvnic->netdev);
|
||||
|
||||
spin_lock(&nesvnic->port_ibevent_lock);
|
||||
if (nesdev->iw_status == 0) {
|
||||
nesdev->iw_status = 1;
|
||||
nes_port_ibevent(nesvnic);
|
||||
}
|
||||
spin_unlock(&nesvnic->port_ibevent_lock);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
nesadapter->mac_link_down[mac_index] = 1;
|
||||
list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) {
|
||||
if (nesvnic->linkup == 1) {
|
||||
printk(PFX "The Link is now down for port %s, netdev %p.\n",
|
||||
nesvnic->netdev->name, nesvnic->netdev);
|
||||
if (!(netif_queue_stopped(nesvnic->netdev)))
|
||||
netif_stop_queue(nesvnic->netdev);
|
||||
nesvnic->linkup = 0;
|
||||
netif_carrier_off(nesvnic->netdev);
|
||||
|
||||
spin_lock(&nesvnic->port_ibevent_lock);
|
||||
if (nesdev->iw_status == 1) {
|
||||
nesdev->iw_status = 0;
|
||||
nes_port_ibevent(nesvnic);
|
||||
}
|
||||
spin_unlock(&nesvnic->port_ibevent_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nesdev->link_recheck++ < NES_LINK_RECHECK_MAX)
|
||||
schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY);
|
||||
else
|
||||
nesdev->link_recheck = 0;
|
||||
|
||||
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user