diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic')
7 files changed, 28 insertions, 15 deletions
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 3010abb55fbd..32058614151a 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | |||
@@ -1602,13 +1602,13 @@ netxen_process_lro(struct netxen_adapter *adapter, | |||
1602 | u32 seq_number; | 1602 | u32 seq_number; |
1603 | u8 vhdr_len = 0; | 1603 | u8 vhdr_len = 0; |
1604 | 1604 | ||
1605 | if (unlikely(ring > adapter->max_rds_rings)) | 1605 | if (unlikely(ring >= adapter->max_rds_rings)) |
1606 | return NULL; | 1606 | return NULL; |
1607 | 1607 | ||
1608 | rds_ring = &recv_ctx->rds_rings[ring]; | 1608 | rds_ring = &recv_ctx->rds_rings[ring]; |
1609 | 1609 | ||
1610 | index = netxen_get_lro_sts_refhandle(sts_data0); | 1610 | index = netxen_get_lro_sts_refhandle(sts_data0); |
1611 | if (unlikely(index > rds_ring->num_desc)) | 1611 | if (unlikely(index >= rds_ring->num_desc)) |
1612 | return NULL; | 1612 | return NULL; |
1613 | 1613 | ||
1614 | buffer = &rds_ring->rx_buf_arr[index]; | 1614 | buffer = &rds_ring->rx_buf_arr[index]; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 4afdef0cc175..35d48766d842 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -493,6 +493,7 @@ struct qlcnic_hardware_context { | |||
493 | struct qlcnic_mailbox *mailbox; | 493 | struct qlcnic_mailbox *mailbox; |
494 | u8 extend_lb_time; | 494 | u8 extend_lb_time; |
495 | u8 phys_port_id[ETH_ALEN]; | 495 | u8 phys_port_id[ETH_ALEN]; |
496 | u8 lb_mode; | ||
496 | }; | 497 | }; |
497 | 498 | ||
498 | struct qlcnic_adapter_stats { | 499 | struct qlcnic_adapter_stats { |
@@ -584,6 +585,8 @@ struct qlcnic_host_tx_ring { | |||
584 | dma_addr_t phys_addr; | 585 | dma_addr_t phys_addr; |
585 | dma_addr_t hw_cons_phys_addr; | 586 | dma_addr_t hw_cons_phys_addr; |
586 | struct netdev_queue *txq; | 587 | struct netdev_queue *txq; |
588 | /* Lock to protect Tx descriptors cleanup */ | ||
589 | spinlock_t tx_clean_lock; | ||
587 | } ____cacheline_internodealigned_in_smp; | 590 | } ____cacheline_internodealigned_in_smp; |
588 | 591 | ||
589 | /* | 592 | /* |
@@ -815,6 +818,7 @@ struct qlcnic_mac_vlan_list { | |||
815 | 818 | ||
816 | #define QLCNIC_ILB_MODE 0x1 | 819 | #define QLCNIC_ILB_MODE 0x1 |
817 | #define QLCNIC_ELB_MODE 0x2 | 820 | #define QLCNIC_ELB_MODE 0x2 |
821 | #define QLCNIC_LB_MODE_MASK 0x3 | ||
818 | 822 | ||
819 | #define QLCNIC_LINKEVENT 0x1 | 823 | #define QLCNIC_LINKEVENT 0x1 |
820 | #define QLCNIC_LB_RESPONSE 0x2 | 824 | #define QLCNIC_LB_RESPONSE 0x2 |
@@ -1100,7 +1104,6 @@ struct qlcnic_adapter { | |||
1100 | struct qlcnic_filter_hash rx_fhash; | 1104 | struct qlcnic_filter_hash rx_fhash; |
1101 | struct list_head vf_mc_list; | 1105 | struct list_head vf_mc_list; |
1102 | 1106 | ||
1103 | spinlock_t tx_clean_lock; | ||
1104 | spinlock_t mac_learn_lock; | 1107 | spinlock_t mac_learn_lock; |
1105 | /* spinlock for catching rcv filters for eswitch traffic */ | 1108 | /* spinlock for catching rcv filters for eswitch traffic */ |
1106 | spinlock_t rx_mac_learn_lock; | 1109 | spinlock_t rx_mac_learn_lock; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index b3fd1605773e..03eb2ad9611a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -1685,12 +1685,6 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) | |||
1685 | } | 1685 | } |
1686 | } while ((adapter->ahw->linkup && ahw->has_link_events) != 1); | 1686 | } while ((adapter->ahw->linkup && ahw->has_link_events) != 1); |
1687 | 1687 | ||
1688 | /* Make sure carrier is off and queue is stopped during loopback */ | ||
1689 | if (netif_running(netdev)) { | ||
1690 | netif_carrier_off(netdev); | ||
1691 | netif_tx_stop_all_queues(netdev); | ||
1692 | } | ||
1693 | |||
1694 | ret = qlcnic_do_lb_test(adapter, mode); | 1688 | ret = qlcnic_do_lb_test(adapter, mode); |
1695 | 1689 | ||
1696 | qlcnic_83xx_clear_lb_mode(adapter, mode); | 1690 | qlcnic_83xx_clear_lb_mode(adapter, mode); |
@@ -2122,6 +2116,7 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter, | |||
2122 | ahw->link_autoneg = MSB(MSW(data[3])); | 2116 | ahw->link_autoneg = MSB(MSW(data[3])); |
2123 | ahw->module_type = MSB(LSW(data[3])); | 2117 | ahw->module_type = MSB(LSW(data[3])); |
2124 | ahw->has_link_events = 1; | 2118 | ahw->has_link_events = 1; |
2119 | ahw->lb_mode = data[4] & QLCNIC_LB_MODE_MASK; | ||
2125 | qlcnic_advert_link_change(adapter, link_status); | 2120 | qlcnic_advert_link_change(adapter, link_status); |
2126 | } | 2121 | } |
2127 | 2122 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index e9c21e5d0ca9..c4262c23ed7c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | |||
@@ -134,6 +134,8 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter, | |||
134 | struct qlcnic_skb_frag *buffrag; | 134 | struct qlcnic_skb_frag *buffrag; |
135 | int i, j; | 135 | int i, j; |
136 | 136 | ||
137 | spin_lock(&tx_ring->tx_clean_lock); | ||
138 | |||
137 | cmd_buf = tx_ring->cmd_buf_arr; | 139 | cmd_buf = tx_ring->cmd_buf_arr; |
138 | for (i = 0; i < tx_ring->num_desc; i++) { | 140 | for (i = 0; i < tx_ring->num_desc; i++) { |
139 | buffrag = cmd_buf->frag_array; | 141 | buffrag = cmd_buf->frag_array; |
@@ -157,6 +159,8 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter, | |||
157 | } | 159 | } |
158 | cmd_buf++; | 160 | cmd_buf++; |
159 | } | 161 | } |
162 | |||
163 | spin_unlock(&tx_ring->tx_clean_lock); | ||
160 | } | 164 | } |
161 | 165 | ||
162 | void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter) | 166 | void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index a215e0f69335..6373f6022486 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -689,6 +689,10 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) | |||
689 | adapter->ahw->linkup = 0; | 689 | adapter->ahw->linkup = 0; |
690 | netif_carrier_off(netdev); | 690 | netif_carrier_off(netdev); |
691 | } else if (!adapter->ahw->linkup && linkup) { | 691 | } else if (!adapter->ahw->linkup && linkup) { |
692 | /* Do not advertise Link up if the port is in loopback mode */ | ||
693 | if (qlcnic_83xx_check(adapter) && adapter->ahw->lb_mode) | ||
694 | return; | ||
695 | |||
692 | netdev_info(netdev, "NIC Link is up\n"); | 696 | netdev_info(netdev, "NIC Link is up\n"); |
693 | adapter->ahw->linkup = 1; | 697 | adapter->ahw->linkup = 1; |
694 | netif_carrier_on(netdev); | 698 | netif_carrier_on(netdev); |
@@ -778,7 +782,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter, | |||
778 | struct net_device *netdev = adapter->netdev; | 782 | struct net_device *netdev = adapter->netdev; |
779 | struct qlcnic_skb_frag *frag; | 783 | struct qlcnic_skb_frag *frag; |
780 | 784 | ||
781 | if (!spin_trylock(&adapter->tx_clean_lock)) | 785 | if (!spin_trylock(&tx_ring->tx_clean_lock)) |
782 | return 1; | 786 | return 1; |
783 | 787 | ||
784 | sw_consumer = tx_ring->sw_consumer; | 788 | sw_consumer = tx_ring->sw_consumer; |
@@ -807,8 +811,9 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter, | |||
807 | break; | 811 | break; |
808 | } | 812 | } |
809 | 813 | ||
814 | tx_ring->sw_consumer = sw_consumer; | ||
815 | |||
810 | if (count && netif_running(netdev)) { | 816 | if (count && netif_running(netdev)) { |
811 | tx_ring->sw_consumer = sw_consumer; | ||
812 | smp_mb(); | 817 | smp_mb(); |
813 | if (netif_tx_queue_stopped(tx_ring->txq) && | 818 | if (netif_tx_queue_stopped(tx_ring->txq) && |
814 | netif_carrier_ok(netdev)) { | 819 | netif_carrier_ok(netdev)) { |
@@ -834,7 +839,8 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter, | |||
834 | */ | 839 | */ |
835 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | 840 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); |
836 | done = (sw_consumer == hw_consumer); | 841 | done = (sw_consumer == hw_consumer); |
837 | spin_unlock(&adapter->tx_clean_lock); | 842 | |
843 | spin_unlock(&tx_ring->tx_clean_lock); | ||
838 | 844 | ||
839 | return done; | 845 | return done; |
840 | } | 846 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index d131ec1321e8..eeec83a0e664 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -1757,7 +1757,6 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1757 | if (qlcnic_sriov_vf_check(adapter)) | 1757 | if (qlcnic_sriov_vf_check(adapter)) |
1758 | qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); | 1758 | qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); |
1759 | smp_mb(); | 1759 | smp_mb(); |
1760 | spin_lock(&adapter->tx_clean_lock); | ||
1761 | netif_carrier_off(netdev); | 1760 | netif_carrier_off(netdev); |
1762 | adapter->ahw->linkup = 0; | 1761 | adapter->ahw->linkup = 0; |
1763 | netif_tx_disable(netdev); | 1762 | netif_tx_disable(netdev); |
@@ -1778,7 +1777,6 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1778 | 1777 | ||
1779 | for (ring = 0; ring < adapter->drv_tx_rings; ring++) | 1778 | for (ring = 0; ring < adapter->drv_tx_rings; ring++) |
1780 | qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); | 1779 | qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); |
1781 | spin_unlock(&adapter->tx_clean_lock); | ||
1782 | } | 1780 | } |
1783 | 1781 | ||
1784 | /* Usage: During suspend and firmware recovery module */ | 1782 | /* Usage: During suspend and firmware recovery module */ |
@@ -2173,6 +2171,7 @@ int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, | |||
2173 | } | 2171 | } |
2174 | memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); | 2172 | memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); |
2175 | tx_ring->cmd_buf_arr = cmd_buf_arr; | 2173 | tx_ring->cmd_buf_arr = cmd_buf_arr; |
2174 | spin_lock_init(&tx_ring->tx_clean_lock); | ||
2176 | } | 2175 | } |
2177 | 2176 | ||
2178 | if (qlcnic_83xx_check(adapter) || | 2177 | if (qlcnic_83xx_check(adapter) || |
@@ -2300,7 +2299,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2300 | rwlock_init(&adapter->ahw->crb_lock); | 2299 | rwlock_init(&adapter->ahw->crb_lock); |
2301 | mutex_init(&adapter->ahw->mem_lock); | 2300 | mutex_init(&adapter->ahw->mem_lock); |
2302 | 2301 | ||
2303 | spin_lock_init(&adapter->tx_clean_lock); | ||
2304 | INIT_LIST_HEAD(&adapter->mac_list); | 2302 | INIT_LIST_HEAD(&adapter->mac_list); |
2305 | 2303 | ||
2306 | qlcnic_register_dcb(adapter); | 2304 | qlcnic_register_dcb(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 98b621fb1227..d14d9a139eef 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -81,9 +81,12 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
81 | if (qlcnic_83xx_pf_check(adapter)) | 81 | if (qlcnic_83xx_pf_check(adapter)) |
82 | num_macs = 1; | 82 | num_macs = 1; |
83 | 83 | ||
84 | info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters; | ||
85 | |||
84 | if (adapter->ahw->pci_func == func) { | 86 | if (adapter->ahw->pci_func == func) { |
85 | info->min_tx_bw = 0; | 87 | info->min_tx_bw = 0; |
86 | info->max_tx_bw = MAX_BW; | 88 | info->max_tx_bw = MAX_BW; |
89 | |||
87 | temp = res->num_rx_ucast_mac_filters - num_macs * num_vfs; | 90 | temp = res->num_rx_ucast_mac_filters - num_macs * num_vfs; |
88 | info->max_rx_ucast_mac_filters = temp; | 91 | info->max_rx_ucast_mac_filters = temp; |
89 | temp = res->num_tx_mac_filters - num_macs * num_vfs; | 92 | temp = res->num_tx_mac_filters - num_macs * num_vfs; |
@@ -92,6 +95,7 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
92 | temp = res->num_rx_mcast_mac_filters - temp; | 95 | temp = res->num_rx_mcast_mac_filters - temp; |
93 | info->max_rx_mcast_mac_filters = temp; | 96 | info->max_rx_mcast_mac_filters = temp; |
94 | 97 | ||
98 | info->max_tx_ques = res->num_tx_queues - sriov->num_vfs; | ||
95 | } else { | 99 | } else { |
96 | id = qlcnic_sriov_func_to_index(adapter, func); | 100 | id = qlcnic_sriov_func_to_index(adapter, func); |
97 | if (id < 0) | 101 | if (id < 0) |
@@ -99,10 +103,13 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter, | |||
99 | vp = sriov->vf_info[id].vp; | 103 | vp = sriov->vf_info[id].vp; |
100 | info->min_tx_bw = vp->min_tx_bw; | 104 | info->min_tx_bw = vp->min_tx_bw; |
101 | info->max_tx_bw = vp->max_tx_bw; | 105 | info->max_tx_bw = vp->max_tx_bw; |
106 | |||
102 | info->max_rx_ucast_mac_filters = num_macs; | 107 | info->max_rx_ucast_mac_filters = num_macs; |
103 | info->max_tx_mac_filters = num_macs; | 108 | info->max_tx_mac_filters = num_macs; |
104 | temp = num_macs * QLCNIC_SRIOV_VF_MAX_MAC; | 109 | temp = num_macs * QLCNIC_SRIOV_VF_MAX_MAC; |
105 | info->max_rx_mcast_mac_filters = temp; | 110 | info->max_rx_mcast_mac_filters = temp; |
111 | |||
112 | info->max_tx_ques = QLCNIC_SINGLE_RING; | ||
106 | } | 113 | } |
107 | 114 | ||
108 | info->max_rx_ip_addr = res->num_destip / max; | 115 | info->max_rx_ip_addr = res->num_destip / max; |