diff options
author | Michael Chan <mchan@broadcom.com> | 2009-10-10 09:46:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-12 02:30:15 -0400 |
commit | 86b53606ebec06b16be81c30fabdf8decc2be6b2 (patch) | |
tree | 4e724ee65b7b004fbadaec1f577e430d846ff0b2 /drivers/net/cnic.c | |
parent | 993ac7b5183f82edc9696cd17faae03523e00e09 (diff) |
cnic: Refactor some code.
Refactor ring init. code for subsequent 10G patches. Also add rtnl_lock()
in cnic_uio_open() to prevent race condition with netdev events.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r-- | drivers/net/cnic.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 46c87ec7960c..eac68f96f808 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -67,9 +67,8 @@ static struct cnic_ops cnic_bnx2_ops = { | |||
67 | .cnic_ctl = cnic_ctl, | 67 | .cnic_ctl = cnic_ctl, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static void cnic_shutdown_bnx2_rx_ring(struct cnic_dev *); | 70 | static void cnic_shutdown_rings(struct cnic_dev *); |
71 | static void cnic_init_bnx2_tx_ring(struct cnic_dev *); | 71 | static void cnic_init_rings(struct cnic_dev *); |
72 | static void cnic_init_bnx2_rx_ring(struct cnic_dev *); | ||
73 | static int cnic_cm_set_pg(struct cnic_sock *); | 72 | static int cnic_cm_set_pg(struct cnic_sock *); |
74 | 73 | ||
75 | static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) | 74 | static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) |
@@ -83,10 +82,16 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) | |||
83 | if (cp->uio_dev != -1) | 82 | if (cp->uio_dev != -1) |
84 | return -EBUSY; | 83 | return -EBUSY; |
85 | 84 | ||
85 | rtnl_lock(); | ||
86 | if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) { | ||
87 | rtnl_unlock(); | ||
88 | return -ENODEV; | ||
89 | } | ||
90 | |||
86 | cp->uio_dev = iminor(inode); | 91 | cp->uio_dev = iminor(inode); |
87 | 92 | ||
88 | cnic_init_bnx2_tx_ring(dev); | 93 | cnic_init_rings(dev); |
89 | cnic_init_bnx2_rx_ring(dev); | 94 | rtnl_unlock(); |
90 | 95 | ||
91 | return 0; | 96 | return 0; |
92 | } | 97 | } |
@@ -96,7 +101,7 @@ static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode) | |||
96 | struct cnic_dev *dev = uinfo->priv; | 101 | struct cnic_dev *dev = uinfo->priv; |
97 | struct cnic_local *cp = dev->cnic_priv; | 102 | struct cnic_local *cp = dev->cnic_priv; |
98 | 103 | ||
99 | cnic_shutdown_bnx2_rx_ring(dev); | 104 | cnic_shutdown_rings(dev); |
100 | 105 | ||
101 | cp->uio_dev = -1; | 106 | cp->uio_dev = -1; |
102 | return 0; | 107 | return 0; |
@@ -675,6 +680,21 @@ error: | |||
675 | return -ENOMEM; | 680 | return -ENOMEM; |
676 | } | 681 | } |
677 | 682 | ||
683 | static void cnic_free_context(struct cnic_dev *dev) | ||
684 | { | ||
685 | struct cnic_local *cp = dev->cnic_priv; | ||
686 | int i; | ||
687 | |||
688 | for (i = 0; i < cp->ctx_blks; i++) { | ||
689 | if (cp->ctx_arr[i].ctx) { | ||
690 | pci_free_consistent(dev->pcidev, cp->ctx_blk_size, | ||
691 | cp->ctx_arr[i].ctx, | ||
692 | cp->ctx_arr[i].mapping); | ||
693 | cp->ctx_arr[i].ctx = NULL; | ||
694 | } | ||
695 | } | ||
696 | } | ||
697 | |||
678 | static void cnic_free_resc(struct cnic_dev *dev) | 698 | static void cnic_free_resc(struct cnic_dev *dev) |
679 | { | 699 | { |
680 | struct cnic_local *cp = dev->cnic_priv; | 700 | struct cnic_local *cp = dev->cnic_priv; |
@@ -702,14 +722,7 @@ static void cnic_free_resc(struct cnic_dev *dev) | |||
702 | cp->l2_ring = NULL; | 722 | cp->l2_ring = NULL; |
703 | } | 723 | } |
704 | 724 | ||
705 | for (i = 0; i < cp->ctx_blks; i++) { | 725 | cnic_free_context(dev); |
706 | if (cp->ctx_arr[i].ctx) { | ||
707 | pci_free_consistent(dev->pcidev, cp->ctx_blk_size, | ||
708 | cp->ctx_arr[i].ctx, | ||
709 | cp->ctx_arr[i].mapping); | ||
710 | cp->ctx_arr[i].ctx = NULL; | ||
711 | } | ||
712 | } | ||
713 | kfree(cp->ctx_arr); | 726 | kfree(cp->ctx_arr); |
714 | cp->ctx_arr = NULL; | 727 | cp->ctx_arr = NULL; |
715 | cp->ctx_blks = 0; | 728 | cp->ctx_blks = 0; |
@@ -808,8 +821,8 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { | |||
808 | uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; | 821 | uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; |
809 | uinfo->mem[0].memtype = UIO_MEM_PHYS; | 822 | uinfo->mem[0].memtype = UIO_MEM_PHYS; |
810 | 823 | ||
811 | uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK; | ||
812 | if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { | 824 | if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { |
825 | uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK; | ||
813 | if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) | 826 | if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) |
814 | uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; | 827 | uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; |
815 | else | 828 | else |
@@ -1012,7 +1025,7 @@ static int cnic_get_kcqes(struct cnic_dev *dev, u16 hw_prod, u16 *sw_prod) | |||
1012 | return last_cnt; | 1025 | return last_cnt; |
1013 | } | 1026 | } |
1014 | 1027 | ||
1015 | static void cnic_chk_bnx2_pkt_rings(struct cnic_local *cp) | 1028 | static void cnic_chk_pkt_rings(struct cnic_local *cp) |
1016 | { | 1029 | { |
1017 | u16 rx_cons = *cp->rx_cons_ptr; | 1030 | u16 rx_cons = *cp->rx_cons_ptr; |
1018 | u16 tx_cons = *cp->tx_cons_ptr; | 1031 | u16 tx_cons = *cp->tx_cons_ptr; |
@@ -1062,7 +1075,7 @@ done: | |||
1062 | 1075 | ||
1063 | cp->kcq_prod_idx = sw_prod; | 1076 | cp->kcq_prod_idx = sw_prod; |
1064 | 1077 | ||
1065 | cnic_chk_bnx2_pkt_rings(cp); | 1078 | cnic_chk_pkt_rings(cp); |
1066 | return status_idx; | 1079 | return status_idx; |
1067 | } | 1080 | } |
1068 | 1081 | ||
@@ -1100,7 +1113,7 @@ done: | |||
1100 | CNIC_WR16(dev, cp->kcq_io_addr, sw_prod); | 1113 | CNIC_WR16(dev, cp->kcq_io_addr, sw_prod); |
1101 | cp->kcq_prod_idx = sw_prod; | 1114 | cp->kcq_prod_idx = sw_prod; |
1102 | 1115 | ||
1103 | cnic_chk_bnx2_pkt_rings(cp); | 1116 | cnic_chk_pkt_rings(cp); |
1104 | 1117 | ||
1105 | cp->last_status_idx = status_idx; | 1118 | cp->last_status_idx = status_idx; |
1106 | CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num | | 1119 | CNIC_WR(dev, BNX2_PCICFG_INT_ACK_CMD, cp->int_num | |
@@ -2464,6 +2477,21 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
2464 | return 0; | 2477 | return 0; |
2465 | } | 2478 | } |
2466 | 2479 | ||
2480 | static void cnic_init_rings(struct cnic_dev *dev) | ||
2481 | { | ||
2482 | if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { | ||
2483 | cnic_init_bnx2_tx_ring(dev); | ||
2484 | cnic_init_bnx2_rx_ring(dev); | ||
2485 | } | ||
2486 | } | ||
2487 | |||
2488 | static void cnic_shutdown_rings(struct cnic_dev *dev) | ||
2489 | { | ||
2490 | if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { | ||
2491 | cnic_shutdown_bnx2_rx_ring(dev); | ||
2492 | } | ||
2493 | } | ||
2494 | |||
2467 | static int cnic_register_netdev(struct cnic_dev *dev) | 2495 | static int cnic_register_netdev(struct cnic_dev *dev) |
2468 | { | 2496 | { |
2469 | struct cnic_local *cp = dev->cnic_priv; | 2497 | struct cnic_local *cp = dev->cnic_priv; |