From: Mike Christie <mchristi@redhat.com> Date: Thu, 18 Nov 2010 17:00:46 -0500 Subject: [net] cnic: Add cnic_uio_dev struct Message-id: <1290099647-9514-4-git-send-email-mchristi@redhat.com> Patchwork-id: 29494 O-Subject: [RHEL 5.6 PATCH 3/4] cnic: Add cnic_uio_dev struct Bugzilla: 651287 RH-Acked-by: David S. Miller <davem@redhat.com> From: Mike Christie <mchristi@redhat.com> This is for bz 651287. >From upstream commit: commit cd801536c236e287f1d3eeee428abf9ffd523ede Author: Michael Chan <mchan@broadcom.com> Date: Wed Oct 13 14:06:49 2010 +0000 cnic: Add cnic_uio_dev struct and put all uio related structures and ring buffers in it. This allows uio operations to be done independent of the cnic device structures. diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index f70aa9f..3ab2408 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -86,22 +86,24 @@ static int cnic_cm_set_pg(struct cnic_sock *); static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) { - struct cnic_dev *dev = uinfo->priv; - struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = uinfo->priv; + struct cnic_dev *dev; if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (cp->uio_dev != -1) + if (udev->uio_dev != -1) return -EBUSY; rtnl_lock(); + dev = udev->dev; + if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) { rtnl_unlock(); return -ENODEV; } - cp->uio_dev = iminor(inode); + udev->uio_dev = iminor(inode); cnic_init_rings(dev); rtnl_unlock(); @@ -111,12 +113,12 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode) { - struct cnic_dev *dev = uinfo->priv; - struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = uinfo->priv; + struct cnic_dev *dev = udev->dev; cnic_shutdown_rings(dev); - cp->uio_dev = -1; + udev->uio_dev = -1; return 0; } @@ -273,8 +275,9 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, u16 len = 0; u32 msg_type = ISCSI_KEVENT_IF_DOWN; struct cnic_ulp_ops *ulp_ops; + struct cnic_uio_dev *udev = cp->udev; - if (cp->uio_dev == -1) + if (!udev || udev->uio_dev == -1) return -ENODEV; if (csk) { @@ -406,8 +409,7 @@ static void cnic_uio_stop(void) list_for_each_entry(dev, &cnic_dev_list, list) { struct cnic_local *cp = dev->cnic_priv; - if (cp->cnic_uinfo) - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); } read_unlock(&cnic_dev_lock); } @@ -774,48 +776,44 @@ static void cnic_free_context(struct cnic_dev *dev) } } -static void __cnic_free_uio(struct cnic_dev *dev) +static void __cnic_free_uio(struct cnic_uio_dev *udev) { - struct cnic_local *cp = dev->cnic_priv; + uio_unregister_device(&udev->cnic_uinfo); - if (cp->cnic_uinfo) - uio_unregister_device(cp->cnic_uinfo); - - kfree(cp->cnic_uinfo); - cp->cnic_uinfo = NULL; - - if (cp->l2_buf) { - dma_free_coherent(&dev->pcidev->dev, cp->l2_buf_size, - cp->l2_buf, cp->l2_buf_map); - cp->l2_buf = NULL; + if (udev->l2_buf) { + dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size, + udev->l2_buf, udev->l2_buf_map); + udev->l2_buf = NULL; } - if (cp->l2_ring) { - dma_free_coherent(&dev->pcidev->dev, cp->l2_ring_size, - cp->l2_ring, cp->l2_ring_map); - cp->l2_ring = NULL; + if (udev->l2_ring) { + dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size, + udev->l2_ring, udev->l2_ring_map); + udev->l2_ring = NULL; } } -static void cnic_free_uio(struct cnic_dev *dev) +static void cnic_free_uio(struct cnic_uio_dev *udev) { - if (!dev) + if (!udev) return; - __cnic_free_uio(dev); + __cnic_free_uio(udev); } static void cnic_free_resc(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; int i = 0; - if (cp->cnic_uinfo) { - while (cp->uio_dev != -1 && i < 15) { + if (udev) { + while (udev->uio_dev != -1 && i < 15) { msleep(100); i++; } - cnic_free_uio(dev); + cnic_free_uio(udev); + cp->udev = NULL; } cnic_free_context(dev); @@ -886,37 +884,53 @@ static int cnic_alloc_context(struct cnic_dev *dev) return 0; } -static int cnic_alloc_l2_rings(struct cnic_dev *dev, int pages) +static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev; + + udev = kzalloc(sizeof(struct cnic_uio_dev), GFP_ATOMIC); + if (!udev) + return -ENOMEM; + + udev->uio_dev = -1; - cp->l2_ring_size = pages * BCM_PAGE_SIZE; - cp->l2_ring = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_ring_size, - &cp->l2_ring_map, - GFP_KERNEL | __GFP_COMP); - if (!cp->l2_ring) + udev->dev = dev; + udev->pdev = dev->pcidev; + udev->l2_ring_size = pages * BCM_PAGE_SIZE; + udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, + &udev->l2_ring_map, + GFP_KERNEL | __GFP_COMP); + if (!udev->l2_ring) return -ENOMEM; - cp->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; - cp->l2_buf_size = PAGE_ALIGN(cp->l2_buf_size); - cp->l2_buf = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_buf_size, - &cp->l2_buf_map, - GFP_KERNEL | __GFP_COMP); - if (!cp->l2_buf) + udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; + udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); + udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, + &udev->l2_buf_map, + GFP_KERNEL | __GFP_COMP); + if (!udev->l2_buf) return -ENOMEM; + cp->udev = udev; + return 0; } -static int cnic_alloc_uio(struct cnic_dev *dev) { +static int cnic_init_uio(struct cnic_dev *dev) +{ struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; struct uio_info *uinfo; - int ret; + int ret = 0; - uinfo = kzalloc(sizeof(*uinfo), GFP_ATOMIC); - if (!uinfo) + if (!udev) return -ENOMEM; + udev->uio_dev = -1; + + uinfo = &udev->cnic_uinfo; + uinfo->mem[0].addr = dev->netdev->base_addr; uinfo->mem[0].internal_addr = dev->regview; uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; @@ -924,7 +938,7 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & - PAGE_MASK; + PAGE_MASK; if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; else @@ -941,12 +955,12 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { uinfo->mem[1].memtype = UIO_MEM_LOGICAL; - uinfo->mem[2].addr = (unsigned long) cp->l2_ring; - uinfo->mem[2].size = cp->l2_ring_size; + uinfo->mem[2].addr = (unsigned long) udev->l2_ring; + uinfo->mem[2].size = udev->l2_ring_size; uinfo->mem[2].memtype = UIO_MEM_LOGICAL; - uinfo->mem[3].addr = (unsigned long) cp->l2_buf; - uinfo->mem[3].size = cp->l2_buf_size; + uinfo->mem[3].addr = (unsigned long) udev->l2_buf; + uinfo->mem[3].size = udev->l2_buf_size; uinfo->mem[3].memtype = UIO_MEM_LOGICAL; uinfo->version = CNIC_MODULE_VERSION; @@ -955,16 +969,11 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { uinfo->open = cnic_uio_open; uinfo->release = cnic_uio_close; - uinfo->priv = dev; + uinfo->priv = udev; - ret = uio_register_device(&dev->pcidev->dev, uinfo); - if (ret) { - kfree(uinfo); - return ret; - } + ret = uio_register_device(&udev->pdev->dev, uinfo); - cp->cnic_uinfo = uinfo; - return 0; + return ret; } static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) @@ -986,11 +995,11 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) if (ret) goto error; - ret = cnic_alloc_l2_rings(dev, 2); + ret = cnic_alloc_uio_rings(dev, 2); if (ret) goto error; - ret = cnic_alloc_uio(dev); + ret = cnic_init_uio(dev); if (ret) goto error; @@ -1133,11 +1142,11 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->l2_rx_ring_size = 15; - ret = cnic_alloc_l2_rings(dev, 4); + ret = cnic_alloc_uio_rings(dev, 4); if (ret) goto error; - ret = cnic_alloc_uio(dev); + ret = cnic_init_uio(dev); if (ret) goto error; @@ -2172,8 +2181,9 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod) static int cnic_l2_completion(struct cnic_local *cp) { u16 hw_cons, sw_cons; + struct cnic_uio_dev *udev = cp->udev; union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *) - (cp->l2_ring + (2 * BCM_PAGE_SIZE)); + (udev->l2_ring + (2 * BCM_PAGE_SIZE)); u32 cmd; int comp = 0; @@ -2219,7 +2229,8 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp) cp->tx_cons = tx_cons; cp->rx_cons = rx_cons; - uio_event_notify(cp->cnic_uinfo); + if (cp->udev) + uio_event_notify(&cp->udev->cnic_uinfo); } if (comp) clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); @@ -2416,8 +2427,7 @@ static void cnic_ulp_stop(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; int if_type; - if (cp->cnic_uinfo) - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { struct cnic_ulp_ops *ulp_ops; @@ -3560,11 +3570,12 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; + struct cnic_uio_dev *udev = cp->udev; u32 cid_addr, tx_cid, sb_id; u32 val, offset0, offset1, offset2, offset3; int i; struct tx_bd *txbd; - dma_addr_t buf_map; + dma_addr_t buf_map, ring_map = udev->l2_ring_map; struct status_block *s_blk = cp->status_blk.gen; sb_id = cp->status_blk_num; @@ -3606,18 +3617,18 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16); cnic_ctx_wr(dev, cid_addr, offset1, val); - txbd = (struct tx_bd *) cp->l2_ring; + txbd = (struct tx_bd *) udev->l2_ring; - buf_map = cp->l2_buf_map; + buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i++, txbd++) { txbd->tx_bd_haddr_hi = (u64) buf_map >> 32; txbd->tx_bd_haddr_lo = (u64) buf_map & 0xffffffff; } - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; cnic_ctx_wr(dev, cid_addr, offset2, val); txbd->tx_bd_haddr_hi = val; - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; cnic_ctx_wr(dev, cid_addr, offset3, val); txbd->tx_bd_haddr_lo = val; } @@ -3626,10 +3637,12 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; + struct cnic_uio_dev *udev = cp->udev; u32 cid_addr, sb_id, val, coal_reg, coal_val; int i; struct rx_bd *rxbd; struct status_block *s_blk = cp->status_blk.gen; + dma_addr_t ring_map = udev->l2_ring_map; sb_id = cp->status_blk_num; cnic_init_context(dev, 2); @@ -3663,22 +3676,22 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); - rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE); + rxbd = (struct rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; - buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size); + buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size); rxbd->rx_bd_len = cp->l2_single_buf_size; rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; rxbd->rx_bd_haddr_hi = (u64) buf_map >> 32; rxbd->rx_bd_haddr_lo = (u64) buf_map & 0xffffffff; } - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val); rxbd->rx_bd_haddr_hi = val; - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val); rxbd->rx_bd_haddr_lo = val; @@ -3949,10 +3962,11 @@ static void cnic_disable_bnx2x_int_sync(struct cnic_dev *dev) static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring; + struct cnic_uio_dev *udev = cp->udev; + union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) udev->l2_ring; struct eth_context *context; struct regpair context_addr; - dma_addr_t buf_map; + dma_addr_t buf_map, ring_map = udev->l2_ring_map; int func = CNIC_FUNC(cp); int port = CNIC_PORT(cp); int i; @@ -3961,7 +3975,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) memset(txbd, 0, BCM_PAGE_SIZE); - buf_map = cp->l2_buf_map; + buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i += 3, txbd += 3) { struct eth_tx_start_bd *start_bd = &txbd->start_bd; struct eth_tx_bd *reg_bd = &((txbd + 2)->reg_bd); @@ -3980,12 +3994,12 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) } context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 1, &context_addr); - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; txbd->next_bd.addr_hi = cpu_to_le32(val); context->xstorm_st_context.tx_bd_page_base_hi = val; - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; txbd->next_bd.addr_lo = cpu_to_le32(val); context->xstorm_st_context.tx_bd_page_base_lo = val; @@ -4019,10 +4033,11 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring + + struct cnic_uio_dev *udev = cp->udev; + struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) - (cp->l2_ring + (2 * BCM_PAGE_SIZE)); + (udev->l2_ring + (2 * BCM_PAGE_SIZE)); struct eth_context *context; struct regpair context_addr; int i; @@ -4030,24 +4045,25 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) int func = CNIC_FUNC(cp); int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); u32 val; + dma_addr_t ring_map = udev->l2_ring_map; struct tstorm_eth_client_config tstorm_client = {0}; for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; - buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size); + buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size); rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32); rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); } context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 0, &context_addr); - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; rxbd->addr_hi = cpu_to_le32(val); context->ustorm_st_context.common.bd_page_base_hi = val; - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; rxbd->addr_lo = cpu_to_le32(val); context->ustorm_st_context.common.bd_page_base_lo = val; @@ -4071,7 +4087,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) ETH_CONNECTION_TYPE); rxcqe += BNX2X_MAX_RCQ_DESC_CNT; - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) >> 32; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) >> 32; rxcqe->addr_hi = cpu_to_le32(val); CNIC_WR(dev, BAR_USTRORM_INTMEM + @@ -4080,7 +4096,7 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) CNIC_WR(dev, BAR_USTRORM_INTMEM + USTORM_CQE_PAGE_NEXT_OFFSET(port, cli) + 4, val); - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; rxcqe->addr_lo = cpu_to_le32(val); CNIC_WR(dev, BAR_USTRORM_INTMEM + @@ -4450,7 +4466,7 @@ static void cnic_stop_hw(struct cnic_dev *dev) /* Need to wait for the ring shutdown event to complete * before clearing the CNIC_UP flag. */ - while (cp->uio_dev != -1 && i < 15) { + while (cp->udev->uio_dev != -1 && i < 15) { msleep(100); i++; } @@ -4504,7 +4520,6 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev, cp = cdev->cnic_priv; cp->dev = cdev; - cp->uio_dev = -1; cp->l2_single_buf_size = 0x400; cp->l2_rx_ring_size = 3; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 1797c62..842f6ca 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -170,6 +170,23 @@ struct cnic_context { } proto; }; +struct cnic_uio_dev { + struct uio_info cnic_uinfo; + u32 uio_dev; + + int l2_ring_size; + void *l2_ring; + dma_addr_t l2_ring_map; + + int l2_buf_size; + void *l2_buf; + dma_addr_t l2_buf_map; + + struct cnic_dev *dev; + struct pci_dev *pdev; + struct list_head list; +}; + struct cnic_local { spinlock_t cnic_ulp_lock; @@ -189,14 +206,9 @@ struct cnic_local { struct cnic_eth_dev *ethdev; - void *l2_ring; - dma_addr_t l2_ring_map; - int l2_ring_size; - int l2_rx_ring_size; + struct cnic_uio_dev *udev; - void *l2_buf; - dma_addr_t l2_buf_map; - int l2_buf_size; + int l2_rx_ring_size; int l2_single_buf_size; u16 *rx_cons_ptr; @@ -271,9 +283,6 @@ struct cnic_local { int func; u32 shmem_base; - u32 uio_dev; - struct uio_info *cnic_uinfo; - struct cnic_ops *cnic_ops; int (*start_hw)(struct cnic_dev *); void (*stop_hw)(struct cnic_dev *);