aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_main.c198
1 files changed, 135 insertions, 63 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index fc721564e69e..ee573fe52a8e 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -22,6 +22,7 @@
22 * 22 *
23 */ 23 */
24 24
25#include <linux/slab.h>
25#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
26#include <linux/interrupt.h> 27#include <linux/interrupt.h>
27 28
@@ -207,6 +208,9 @@ qlcnic_napi_enable(struct qlcnic_adapter *adapter)
207 struct qlcnic_host_sds_ring *sds_ring; 208 struct qlcnic_host_sds_ring *sds_ring;
208 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; 209 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
209 210
211 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
212 return;
213
210 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 214 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
211 sds_ring = &recv_ctx->sds_rings[ring]; 215 sds_ring = &recv_ctx->sds_rings[ring];
212 napi_enable(&sds_ring->napi); 216 napi_enable(&sds_ring->napi);
@@ -221,6 +225,9 @@ qlcnic_napi_disable(struct qlcnic_adapter *adapter)
221 struct qlcnic_host_sds_ring *sds_ring; 225 struct qlcnic_host_sds_ring *sds_ring;
222 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; 226 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
223 227
228 if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
229 return;
230
224 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 231 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
225 sds_ring = &recv_ctx->sds_rings[ring]; 232 sds_ring = &recv_ctx->sds_rings[ring];
226 qlcnic_disable_int(sds_ring); 233 qlcnic_disable_int(sds_ring);
@@ -649,7 +656,10 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
649 if (err) 656 if (err)
650 return err; 657 return err;
651 658
652 if (!qlcnic_can_start_firmware(adapter)) 659 err = qlcnic_can_start_firmware(adapter);
660 if (err < 0)
661 return err;
662 else if (!err)
653 goto wait_init; 663 goto wait_init;
654 664
655 first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc)); 665 first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc));
@@ -949,11 +959,11 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
949 adapter->max_sds_rings = max_sds_rings; 959 adapter->max_sds_rings = max_sds_rings;
950 960
951 if (qlcnic_attach(adapter)) 961 if (qlcnic_attach(adapter))
952 return; 962 goto out;
953 963
954 if (netif_running(netdev)) 964 if (netif_running(netdev))
955 __qlcnic_up(adapter, netdev); 965 __qlcnic_up(adapter, netdev);
956 966out:
957 netif_device_attach(netdev); 967 netif_device_attach(netdev);
958} 968}
959 969
@@ -975,8 +985,10 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
975 adapter->diag_test = test; 985 adapter->diag_test = test;
976 986
977 ret = qlcnic_attach(adapter); 987 ret = qlcnic_attach(adapter);
978 if (ret) 988 if (ret) {
989 netif_device_attach(netdev);
979 return ret; 990 return ret;
991 }
980 992
981 if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) { 993 if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
982 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 994 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -1009,16 +1021,12 @@ qlcnic_reset_context(struct qlcnic_adapter *adapter)
1009 if (netif_running(netdev)) { 1021 if (netif_running(netdev)) {
1010 err = qlcnic_attach(adapter); 1022 err = qlcnic_attach(adapter);
1011 if (!err) 1023 if (!err)
1012 err = __qlcnic_up(adapter, netdev); 1024 __qlcnic_up(adapter, netdev);
1013
1014 if (err)
1015 goto done;
1016 } 1025 }
1017 1026
1018 netif_device_attach(netdev); 1027 netif_device_attach(netdev);
1019 } 1028 }
1020 1029
1021done:
1022 clear_bit(__QLCNIC_RESETTING, &adapter->state); 1030 clear_bit(__QLCNIC_RESETTING, &adapter->state);
1023 return err; 1031 return err;
1024} 1032}
@@ -1138,6 +1146,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1138 goto err_out_iounmap; 1146 goto err_out_iounmap;
1139 } 1147 }
1140 1148
1149 qlcnic_setup_idc_param(adapter);
1141 1150
1142 err = qlcnic_start_firmware(adapter); 1151 err = qlcnic_start_firmware(adapter);
1143 if (err) 1152 if (err)
@@ -1333,6 +1342,7 @@ err_out_detach:
1333 qlcnic_detach(adapter); 1342 qlcnic_detach(adapter);
1334err_out: 1343err_out:
1335 qlcnic_clr_all_drv_state(adapter); 1344 qlcnic_clr_all_drv_state(adapter);
1345 netif_device_attach(netdev);
1336 return err; 1346 return err;
1337} 1347}
1338#endif 1348#endif
@@ -1569,6 +1579,11 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1569 int frag_count, no_of_desc; 1579 int frag_count, no_of_desc;
1570 u32 num_txd = tx_ring->num_desc; 1580 u32 num_txd = tx_ring->num_desc;
1571 1581
1582 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
1583 netif_stop_queue(netdev);
1584 return NETDEV_TX_BUSY;
1585 }
1586
1572 frag_count = skb_shinfo(skb)->nr_frags + 1; 1587 frag_count = skb_shinfo(skb)->nr_frags + 1;
1573 1588
1574 /* 4 fragments per cmd des */ 1589 /* 4 fragments per cmd des */
@@ -1585,8 +1600,10 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1585 1600
1586 pdev = adapter->pdev; 1601 pdev = adapter->pdev;
1587 1602
1588 if (qlcnic_map_tx_skb(pdev, skb, pbuf)) 1603 if (qlcnic_map_tx_skb(pdev, skb, pbuf)) {
1604 adapter->stats.tx_dma_map_error++;
1589 goto drop_packet; 1605 goto drop_packet;
1606 }
1590 1607
1591 pbuf->skb = skb; 1608 pbuf->skb = skb;
1592 pbuf->frag_count = frag_count; 1609 pbuf->frag_count = frag_count;
@@ -1738,6 +1755,7 @@ static void qlcnic_tx_timeout_task(struct work_struct *work)
1738request_reset: 1755request_reset:
1739 adapter->need_fw_reset = 1; 1756 adapter->need_fw_reset = 1;
1740 clear_bit(__QLCNIC_RESETTING, &adapter->state); 1757 clear_bit(__QLCNIC_RESETTING, &adapter->state);
1758 QLCDB(adapter, DRV, "Resetting adapter\n");
1741} 1759}
1742 1760
1743static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 1761static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
@@ -1942,8 +1960,8 @@ static void qlcnic_poll_controller(struct net_device *netdev)
1942} 1960}
1943#endif 1961#endif
1944 1962
1945static void 1963static int
1946qlcnic_set_drv_state(struct qlcnic_adapter *adapter, int state) 1964qlcnic_set_drv_state(struct qlcnic_adapter *adapter, u8 state)
1947{ 1965{
1948 u32 val; 1966 u32 val;
1949 1967
@@ -1951,18 +1969,20 @@ qlcnic_set_drv_state(struct qlcnic_adapter *adapter, int state)
1951 state != QLCNIC_DEV_NEED_QUISCENT); 1969 state != QLCNIC_DEV_NEED_QUISCENT);
1952 1970
1953 if (qlcnic_api_lock(adapter)) 1971 if (qlcnic_api_lock(adapter))
1954 return ; 1972 return -EIO;
1955 1973
1956 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 1974 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
1957 1975
1958 if (state == QLCNIC_DEV_NEED_RESET) 1976 if (state == QLCNIC_DEV_NEED_RESET)
1959 val |= ((u32)0x1 << (adapter->portnum * 4)); 1977 QLC_DEV_SET_RST_RDY(val, adapter->portnum);
1960 else if (state == QLCNIC_DEV_NEED_QUISCENT) 1978 else if (state == QLCNIC_DEV_NEED_QUISCENT)
1961 val |= ((u32)0x1 << ((adapter->portnum * 4) + 1)); 1979 QLC_DEV_SET_QSCNT_RDY(val, adapter->portnum);
1962 1980
1963 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); 1981 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
1964 1982
1965 qlcnic_api_unlock(adapter); 1983 qlcnic_api_unlock(adapter);
1984
1985 return 0;
1966} 1986}
1967 1987
1968static int 1988static int
@@ -1974,7 +1994,7 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter)
1974 return -EBUSY; 1994 return -EBUSY;
1975 1995
1976 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 1996 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
1977 val &= ~((u32)0x3 << (adapter->portnum * 4)); 1997 QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum);
1978 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); 1998 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
1979 1999
1980 qlcnic_api_unlock(adapter); 2000 qlcnic_api_unlock(adapter);
@@ -1991,14 +2011,14 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter)
1991 goto err; 2011 goto err;
1992 2012
1993 val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); 2013 val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
1994 val &= ~((u32)0x1 << (adapter->portnum * 4)); 2014 QLC_DEV_CLR_REF_CNT(val, adapter->portnum);
1995 QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); 2015 QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
1996 2016
1997 if (!(val & 0x11111111)) 2017 if (!(val & 0x11111111))
1998 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD); 2018 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD);
1999 2019
2000 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 2020 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
2001 val &= ~((u32)0x3 << (adapter->portnum * 4)); 2021 QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum);
2002 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2022 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
2003 2023
2004 qlcnic_api_unlock(adapter); 2024 qlcnic_api_unlock(adapter);
@@ -2008,6 +2028,7 @@ err:
2008 clear_bit(__QLCNIC_RESETTING, &adapter->state); 2028 clear_bit(__QLCNIC_RESETTING, &adapter->state);
2009} 2029}
2010 2030
2031/* Grab api lock, before checking state */
2011static int 2032static int
2012qlcnic_check_drv_state(struct qlcnic_adapter *adapter) 2033qlcnic_check_drv_state(struct qlcnic_adapter *adapter)
2013{ 2034{
@@ -2027,26 +2048,27 @@ static int
2027qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) 2048qlcnic_can_start_firmware(struct qlcnic_adapter *adapter)
2028{ 2049{
2029 u32 val, prev_state; 2050 u32 val, prev_state;
2030 int cnt = 0; 2051 u8 dev_init_timeo = adapter->dev_init_timeo;
2031 int portnum = adapter->portnum; 2052 u8 portnum = adapter->portnum;
2053
2054 if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state))
2055 return 1;
2032 2056
2033 if (qlcnic_api_lock(adapter)) 2057 if (qlcnic_api_lock(adapter))
2034 return -1; 2058 return -1;
2035 2059
2036 val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); 2060 val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
2037 if (!(val & ((int)0x1 << (portnum * 4)))) { 2061 if (!(val & (1 << (portnum * 4)))) {
2038 val |= ((u32)0x1 << (portnum * 4)); 2062 QLC_DEV_SET_REF_CNT(val, portnum);
2039 QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); 2063 QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val);
2040 } else if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) {
2041 goto start_fw;
2042 } 2064 }
2043 2065
2044 prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); 2066 prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2067 QLCDB(adapter, HW, "Device state = %u\n", prev_state);
2045 2068
2046 switch (prev_state) { 2069 switch (prev_state) {
2047 case QLCNIC_DEV_COLD: 2070 case QLCNIC_DEV_COLD:
2048start_fw: 2071 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING);
2049 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITALIZING);
2050 qlcnic_api_unlock(adapter); 2072 qlcnic_api_unlock(adapter);
2051 return 1; 2073 return 1;
2052 2074
@@ -2056,35 +2078,43 @@ start_fw:
2056 2078
2057 case QLCNIC_DEV_NEED_RESET: 2079 case QLCNIC_DEV_NEED_RESET:
2058 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 2080 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
2059 val |= ((u32)0x1 << (portnum * 4)); 2081 QLC_DEV_SET_RST_RDY(val, portnum);
2060 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2082 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
2061 break; 2083 break;
2062 2084
2063 case QLCNIC_DEV_NEED_QUISCENT: 2085 case QLCNIC_DEV_NEED_QUISCENT:
2064 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 2086 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
2065 val |= ((u32)0x1 << ((portnum * 4) + 1)); 2087 QLC_DEV_SET_QSCNT_RDY(val, portnum);
2066 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2088 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
2067 break; 2089 break;
2068 2090
2069 case QLCNIC_DEV_FAILED: 2091 case QLCNIC_DEV_FAILED:
2070 qlcnic_api_unlock(adapter); 2092 qlcnic_api_unlock(adapter);
2071 return -1; 2093 return -1;
2094
2095 case QLCNIC_DEV_INITIALIZING:
2096 case QLCNIC_DEV_QUISCENT:
2097 break;
2072 } 2098 }
2073 2099
2074 qlcnic_api_unlock(adapter); 2100 qlcnic_api_unlock(adapter);
2075 msleep(1000); 2101
2076 while ((QLCRD32(adapter, QLCNIC_CRB_DEV_STATE) != QLCNIC_DEV_READY) && 2102 do {
2077 ++cnt < 20)
2078 msleep(1000); 2103 msleep(1000);
2104 } while ((QLCRD32(adapter, QLCNIC_CRB_DEV_STATE) != QLCNIC_DEV_READY)
2105 && --dev_init_timeo);
2079 2106
2080 if (cnt >= 20) 2107 if (!dev_init_timeo) {
2108 dev_err(&adapter->pdev->dev,
2109 "Waiting for device to initialize timeout\n");
2081 return -1; 2110 return -1;
2111 }
2082 2112
2083 if (qlcnic_api_lock(adapter)) 2113 if (qlcnic_api_lock(adapter))
2084 return -1; 2114 return -1;
2085 2115
2086 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); 2116 val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE);
2087 val &= ~((u32)0x3 << (portnum * 4)); 2117 QLC_DEV_CLR_RST_QSCNT(val, portnum);
2088 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); 2118 QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val);
2089 2119
2090 qlcnic_api_unlock(adapter); 2120 qlcnic_api_unlock(adapter);
@@ -2097,44 +2127,60 @@ qlcnic_fwinit_work(struct work_struct *work)
2097{ 2127{
2098 struct qlcnic_adapter *adapter = container_of(work, 2128 struct qlcnic_adapter *adapter = container_of(work,
2099 struct qlcnic_adapter, fw_work.work); 2129 struct qlcnic_adapter, fw_work.work);
2100 int dev_state; 2130 u32 dev_state = 0xf;
2101 2131
2102 if (++adapter->fw_wait_cnt > FW_POLL_THRESH) 2132 if (qlcnic_api_lock(adapter))
2103 goto err_ret; 2133 goto err_ret;
2104 2134
2105 if (test_bit(__QLCNIC_START_FW, &adapter->state)) { 2135 if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) {
2136 dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n",
2137 adapter->reset_ack_timeo);
2138 goto skip_ack_check;
2139 }
2106 2140
2107 if (qlcnic_check_drv_state(adapter)) { 2141 if (!qlcnic_check_drv_state(adapter)) {
2108 qlcnic_schedule_work(adapter, 2142skip_ack_check:
2109 qlcnic_fwinit_work, FW_POLL_DELAY); 2143 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2110 return; 2144 if (dev_state == QLCNIC_DEV_NEED_RESET) {
2145 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE,
2146 QLCNIC_DEV_INITIALIZING);
2147 set_bit(__QLCNIC_START_FW, &adapter->state);
2148 QLCDB(adapter, DRV, "Restarting fw\n");
2111 } 2149 }
2112 2150
2151 qlcnic_api_unlock(adapter);
2152
2113 if (!qlcnic_start_firmware(adapter)) { 2153 if (!qlcnic_start_firmware(adapter)) {
2114 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 2154 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
2115 return; 2155 return;
2116 } 2156 }
2117
2118 goto err_ret; 2157 goto err_ret;
2119 } 2158 }
2120 2159
2160 qlcnic_api_unlock(adapter);
2161
2121 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); 2162 dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2163 QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state);
2164
2122 switch (dev_state) { 2165 switch (dev_state) {
2123 case QLCNIC_DEV_READY: 2166 case QLCNIC_DEV_NEED_RESET:
2124 if (!qlcnic_start_firmware(adapter)) { 2167 qlcnic_schedule_work(adapter,
2125 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); 2168 qlcnic_fwinit_work, FW_POLL_DELAY);
2126 return; 2169 return;
2127 }
2128 case QLCNIC_DEV_FAILED: 2170 case QLCNIC_DEV_FAILED:
2129 break; 2171 break;
2130 2172
2131 default: 2173 default:
2132 qlcnic_schedule_work(adapter, 2174 if (!qlcnic_start_firmware(adapter)) {
2133 qlcnic_fwinit_work, 2 * FW_POLL_DELAY); 2175 qlcnic_schedule_work(adapter, qlcnic_attach_work, 0);
2134 return; 2176 return;
2177 }
2135 } 2178 }
2136 2179
2137err_ret: 2180err_ret:
2181 dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u "
2182 "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt);
2183 netif_device_attach(adapter->netdev);
2138 qlcnic_clr_all_drv_state(adapter); 2184 qlcnic_clr_all_drv_state(adapter);
2139} 2185}
2140 2186
@@ -2162,7 +2208,8 @@ qlcnic_detach_work(struct work_struct *work)
2162 if (adapter->temp == QLCNIC_TEMP_PANIC) 2208 if (adapter->temp == QLCNIC_TEMP_PANIC)
2163 goto err_ret; 2209 goto err_ret;
2164 2210
2165 qlcnic_set_drv_state(adapter, adapter->dev_state); 2211 if (qlcnic_set_drv_state(adapter, adapter->dev_state))
2212 goto err_ret;
2166 2213
2167 adapter->fw_wait_cnt = 0; 2214 adapter->fw_wait_cnt = 0;
2168 2215
@@ -2171,10 +2218,14 @@ qlcnic_detach_work(struct work_struct *work)
2171 return; 2218 return;
2172 2219
2173err_ret: 2220err_ret:
2221 dev_err(&adapter->pdev->dev, "detach failed; status=%d temp=%d\n",
2222 status, adapter->temp);
2223 netif_device_attach(netdev);
2174 qlcnic_clr_all_drv_state(adapter); 2224 qlcnic_clr_all_drv_state(adapter);
2175 2225
2176} 2226}
2177 2227
2228/*Transit to RESET state from READY state only */
2178static void 2229static void
2179qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) 2230qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
2180{ 2231{
@@ -2185,9 +2236,9 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
2185 2236
2186 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); 2237 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
2187 2238
2188 if (state != QLCNIC_DEV_INITALIZING && state != QLCNIC_DEV_NEED_RESET) { 2239 if (state == QLCNIC_DEV_READY) {
2189 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); 2240 QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET);
2190 set_bit(__QLCNIC_START_FW, &adapter->state); 2241 QLCDB(adapter, DRV, "NEED_RESET state set\n");
2191 } 2242 }
2192 2243
2193 qlcnic_api_unlock(adapter); 2244 qlcnic_api_unlock(adapter);
@@ -2232,9 +2283,8 @@ qlcnic_attach_work(struct work_struct *work)
2232 qlcnic_config_indev_addr(netdev, NETDEV_UP); 2283 qlcnic_config_indev_addr(netdev, NETDEV_UP);
2233 } 2284 }
2234 2285
2235 netif_device_attach(netdev);
2236
2237done: 2286done:
2287 netif_device_attach(netdev);
2238 adapter->fw_fail_cnt = 0; 2288 adapter->fw_fail_cnt = 0;
2239 clear_bit(__QLCNIC_RESETTING, &adapter->state); 2289 clear_bit(__QLCNIC_RESETTING, &adapter->state);
2240 2290
@@ -2284,8 +2334,11 @@ detach:
2284 QLCNIC_DEV_NEED_RESET; 2334 QLCNIC_DEV_NEED_RESET;
2285 2335
2286 if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) && 2336 if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
2287 !test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 2337 !test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) {
2338
2288 qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); 2339 qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
2340 QLCDB(adapter, DRV, "fw recovery scheduled.\n");
2341 }
2289 2342
2290 return 1; 2343 return 1;
2291} 2344}
@@ -2386,14 +2439,21 @@ static int
2386qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, 2439qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
2387 loff_t offset, size_t size) 2440 loff_t offset, size_t size)
2388{ 2441{
2442 size_t crb_size = 4;
2443
2389 if (!(adapter->flags & QLCNIC_DIAG_ENABLED)) 2444 if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
2390 return -EIO; 2445 return -EIO;
2391 2446
2392 if ((size != 4) || (offset & 0x3)) 2447 if (offset < QLCNIC_PCI_CRBSPACE) {
2393 return -EINVAL; 2448 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
2449 QLCNIC_PCI_CAMQM_END))
2450 crb_size = 8;
2451 else
2452 return -EINVAL;
2453 }
2394 2454
2395 if (offset < QLCNIC_PCI_CRBSPACE) 2455 if ((size != crb_size) || (offset & (crb_size-1)))
2396 return -EINVAL; 2456 return -EINVAL;
2397 2457
2398 return 0; 2458 return 0;
2399} 2459}
@@ -2405,14 +2465,20 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr,
2405 struct device *dev = container_of(kobj, struct device, kobj); 2465 struct device *dev = container_of(kobj, struct device, kobj);
2406 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 2466 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
2407 u32 data; 2467 u32 data;
2468 u64 qmdata;
2408 int ret; 2469 int ret;
2409 2470
2410 ret = qlcnic_sysfs_validate_crb(adapter, offset, size); 2471 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
2411 if (ret != 0) 2472 if (ret != 0)
2412 return ret; 2473 return ret;
2413 2474
2414 data = QLCRD32(adapter, offset); 2475 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
2415 memcpy(buf, &data, size); 2476 qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
2477 memcpy(buf, &qmdata, size);
2478 } else {
2479 data = QLCRD32(adapter, offset);
2480 memcpy(buf, &data, size);
2481 }
2416 return size; 2482 return size;
2417} 2483}
2418 2484
@@ -2423,14 +2489,20 @@ qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr,
2423 struct device *dev = container_of(kobj, struct device, kobj); 2489 struct device *dev = container_of(kobj, struct device, kobj);
2424 struct qlcnic_adapter *adapter = dev_get_drvdata(dev); 2490 struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
2425 u32 data; 2491 u32 data;
2492 u64 qmdata;
2426 int ret; 2493 int ret;
2427 2494
2428 ret = qlcnic_sysfs_validate_crb(adapter, offset, size); 2495 ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
2429 if (ret != 0) 2496 if (ret != 0)
2430 return ret; 2497 return ret;
2431 2498
2432 memcpy(&data, buf, size); 2499 if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
2433 QLCWR32(adapter, offset, data); 2500 memcpy(&qmdata, buf, size);
2501 qlcnic_pci_camqm_write_2M(adapter, offset, qmdata);
2502 } else {
2503 memcpy(&data, buf, size);
2504 QLCWR32(adapter, offset, data);
2505 }
2434 return size; 2506 return size;
2435} 2507}
2436 2508