diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 119 |
1 files changed, 74 insertions, 45 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index e4fd5dcdfb4c..ee573fe52a8e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -208,6 +208,9 @@ qlcnic_napi_enable(struct qlcnic_adapter *adapter) | |||
208 | struct qlcnic_host_sds_ring *sds_ring; | 208 | struct qlcnic_host_sds_ring *sds_ring; |
209 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | 209 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; |
210 | 210 | ||
211 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
212 | return; | ||
213 | |||
211 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 214 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
212 | sds_ring = &recv_ctx->sds_rings[ring]; | 215 | sds_ring = &recv_ctx->sds_rings[ring]; |
213 | napi_enable(&sds_ring->napi); | 216 | napi_enable(&sds_ring->napi); |
@@ -222,6 +225,9 @@ qlcnic_napi_disable(struct qlcnic_adapter *adapter) | |||
222 | struct qlcnic_host_sds_ring *sds_ring; | 225 | struct qlcnic_host_sds_ring *sds_ring; |
223 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | 226 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; |
224 | 227 | ||
228 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
229 | return; | ||
230 | |||
225 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 231 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
226 | sds_ring = &recv_ctx->sds_rings[ring]; | 232 | sds_ring = &recv_ctx->sds_rings[ring]; |
227 | qlcnic_disable_int(sds_ring); | 233 | qlcnic_disable_int(sds_ring); |
@@ -1573,6 +1579,11 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1573 | int frag_count, no_of_desc; | 1579 | int frag_count, no_of_desc; |
1574 | u32 num_txd = tx_ring->num_desc; | 1580 | u32 num_txd = tx_ring->num_desc; |
1575 | 1581 | ||
1582 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) { | ||
1583 | netif_stop_queue(netdev); | ||
1584 | return NETDEV_TX_BUSY; | ||
1585 | } | ||
1586 | |||
1576 | frag_count = skb_shinfo(skb)->nr_frags + 1; | 1587 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
1577 | 1588 | ||
1578 | /* 4 fragments per cmd des */ | 1589 | /* 4 fragments per cmd des */ |
@@ -1589,8 +1600,10 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1589 | 1600 | ||
1590 | pdev = adapter->pdev; | 1601 | pdev = adapter->pdev; |
1591 | 1602 | ||
1592 | if (qlcnic_map_tx_skb(pdev, skb, pbuf)) | 1603 | if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { |
1604 | adapter->stats.tx_dma_map_error++; | ||
1593 | goto drop_packet; | 1605 | goto drop_packet; |
1606 | } | ||
1594 | 1607 | ||
1595 | pbuf->skb = skb; | 1608 | pbuf->skb = skb; |
1596 | pbuf->frag_count = frag_count; | 1609 | pbuf->frag_count = frag_count; |
@@ -1947,8 +1960,8 @@ static void qlcnic_poll_controller(struct net_device *netdev) | |||
1947 | } | 1960 | } |
1948 | #endif | 1961 | #endif |
1949 | 1962 | ||
1950 | static void | 1963 | static int |
1951 | qlcnic_set_drv_state(struct qlcnic_adapter *adapter, int state) | 1964 | qlcnic_set_drv_state(struct qlcnic_adapter *adapter, u8 state) |
1952 | { | 1965 | { |
1953 | u32 val; | 1966 | u32 val; |
1954 | 1967 | ||
@@ -1956,18 +1969,20 @@ qlcnic_set_drv_state(struct qlcnic_adapter *adapter, int state) | |||
1956 | state != QLCNIC_DEV_NEED_QUISCENT); | 1969 | state != QLCNIC_DEV_NEED_QUISCENT); |
1957 | 1970 | ||
1958 | if (qlcnic_api_lock(adapter)) | 1971 | if (qlcnic_api_lock(adapter)) |
1959 | return ; | 1972 | return -EIO; |
1960 | 1973 | ||
1961 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | 1974 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); |
1962 | 1975 | ||
1963 | if (state == QLCNIC_DEV_NEED_RESET) | 1976 | if (state == QLCNIC_DEV_NEED_RESET) |
1964 | val |= ((u32)0x1 << (adapter->portnum * 4)); | 1977 | QLC_DEV_SET_RST_RDY(val, adapter->portnum); |
1965 | else if (state == QLCNIC_DEV_NEED_QUISCENT) | 1978 | else if (state == QLCNIC_DEV_NEED_QUISCENT) |
1966 | val |= ((u32)0x1 << ((adapter->portnum * 4) + 1)); | 1979 | QLC_DEV_SET_QSCNT_RDY(val, adapter->portnum); |
1967 | 1980 | ||
1968 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | 1981 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); |
1969 | 1982 | ||
1970 | qlcnic_api_unlock(adapter); | 1983 | qlcnic_api_unlock(adapter); |
1984 | |||
1985 | return 0; | ||
1971 | } | 1986 | } |
1972 | 1987 | ||
1973 | static int | 1988 | static int |
@@ -1979,7 +1994,7 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) | |||
1979 | return -EBUSY; | 1994 | return -EBUSY; |
1980 | 1995 | ||
1981 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | 1996 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); |
1982 | val &= ~((u32)0x3 << (adapter->portnum * 4)); | 1997 | QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); |
1983 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | 1998 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); |
1984 | 1999 | ||
1985 | qlcnic_api_unlock(adapter); | 2000 | qlcnic_api_unlock(adapter); |
@@ -1996,14 +2011,14 @@ qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter) | |||
1996 | goto err; | 2011 | goto err; |
1997 | 2012 | ||
1998 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | 2013 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); |
1999 | val &= ~((u32)0x1 << (adapter->portnum * 4)); | 2014 | QLC_DEV_CLR_REF_CNT(val, adapter->portnum); |
2000 | QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); | 2015 | QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); |
2001 | 2016 | ||
2002 | if (!(val & 0x11111111)) | 2017 | if (!(val & 0x11111111)) |
2003 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD); | 2018 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD); |
2004 | 2019 | ||
2005 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | 2020 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); |
2006 | val &= ~((u32)0x3 << (adapter->portnum * 4)); | 2021 | QLC_DEV_CLR_RST_QSCNT(val, adapter->portnum); |
2007 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | 2022 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); |
2008 | 2023 | ||
2009 | qlcnic_api_unlock(adapter); | 2024 | qlcnic_api_unlock(adapter); |
@@ -2013,6 +2028,7 @@ err: | |||
2013 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 2028 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
2014 | } | 2029 | } |
2015 | 2030 | ||
2031 | /* Grab api lock, before checking state */ | ||
2016 | static int | 2032 | static int |
2017 | qlcnic_check_drv_state(struct qlcnic_adapter *adapter) | 2033 | qlcnic_check_drv_state(struct qlcnic_adapter *adapter) |
2018 | { | 2034 | { |
@@ -2033,17 +2049,18 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) | |||
2033 | { | 2049 | { |
2034 | u32 val, prev_state; | 2050 | u32 val, prev_state; |
2035 | u8 dev_init_timeo = adapter->dev_init_timeo; | 2051 | u8 dev_init_timeo = adapter->dev_init_timeo; |
2036 | int portnum = adapter->portnum; | 2052 | u8 portnum = adapter->portnum; |
2053 | |||
2054 | if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) | ||
2055 | return 1; | ||
2037 | 2056 | ||
2038 | if (qlcnic_api_lock(adapter)) | 2057 | if (qlcnic_api_lock(adapter)) |
2039 | return -1; | 2058 | return -1; |
2040 | 2059 | ||
2041 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | 2060 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); |
2042 | if (!(val & ((int)0x1 << (portnum * 4)))) { | 2061 | if (!(val & (1 << (portnum * 4)))) { |
2043 | val |= ((u32)0x1 << (portnum * 4)); | 2062 | QLC_DEV_SET_REF_CNT(val, portnum); |
2044 | QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); | 2063 | QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); |
2045 | } else if (test_and_clear_bit(__QLCNIC_START_FW, &adapter->state)) { | ||
2046 | goto start_fw; | ||
2047 | } | 2064 | } |
2048 | 2065 | ||
2049 | prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2066 | prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
@@ -2051,8 +2068,7 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) | |||
2051 | 2068 | ||
2052 | switch (prev_state) { | 2069 | switch (prev_state) { |
2053 | case QLCNIC_DEV_COLD: | 2070 | case QLCNIC_DEV_COLD: |
2054 | start_fw: | 2071 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING); |
2055 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITALIZING); | ||
2056 | qlcnic_api_unlock(adapter); | 2072 | qlcnic_api_unlock(adapter); |
2057 | return 1; | 2073 | return 1; |
2058 | 2074 | ||
@@ -2062,19 +2078,23 @@ start_fw: | |||
2062 | 2078 | ||
2063 | case QLCNIC_DEV_NEED_RESET: | 2079 | case QLCNIC_DEV_NEED_RESET: |
2064 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | 2080 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); |
2065 | val |= ((u32)0x1 << (portnum * 4)); | 2081 | QLC_DEV_SET_RST_RDY(val, portnum); |
2066 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | 2082 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); |
2067 | break; | 2083 | break; |
2068 | 2084 | ||
2069 | case QLCNIC_DEV_NEED_QUISCENT: | 2085 | case QLCNIC_DEV_NEED_QUISCENT: |
2070 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | 2086 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); |
2071 | val |= ((u32)0x1 << ((portnum * 4) + 1)); | 2087 | QLC_DEV_SET_QSCNT_RDY(val, portnum); |
2072 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | 2088 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); |
2073 | break; | 2089 | break; |
2074 | 2090 | ||
2075 | case QLCNIC_DEV_FAILED: | 2091 | case QLCNIC_DEV_FAILED: |
2076 | qlcnic_api_unlock(adapter); | 2092 | qlcnic_api_unlock(adapter); |
2077 | return -1; | 2093 | return -1; |
2094 | |||
2095 | case QLCNIC_DEV_INITIALIZING: | ||
2096 | case QLCNIC_DEV_QUISCENT: | ||
2097 | break; | ||
2078 | } | 2098 | } |
2079 | 2099 | ||
2080 | qlcnic_api_unlock(adapter); | 2100 | qlcnic_api_unlock(adapter); |
@@ -2094,7 +2114,7 @@ start_fw: | |||
2094 | return -1; | 2114 | return -1; |
2095 | 2115 | ||
2096 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); | 2116 | val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); |
2097 | val &= ~((u32)0x3 << (portnum * 4)); | 2117 | QLC_DEV_CLR_RST_QSCNT(val, portnum); |
2098 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); | 2118 | QLCWR32(adapter, QLCNIC_CRB_DRV_STATE, val); |
2099 | 2119 | ||
2100 | qlcnic_api_unlock(adapter); | 2120 | qlcnic_api_unlock(adapter); |
@@ -2107,51 +2127,59 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2107 | { | 2127 | { |
2108 | struct qlcnic_adapter *adapter = container_of(work, | 2128 | struct qlcnic_adapter *adapter = container_of(work, |
2109 | struct qlcnic_adapter, fw_work.work); | 2129 | struct qlcnic_adapter, fw_work.work); |
2110 | int dev_state; | 2130 | u32 dev_state = 0xf; |
2111 | 2131 | ||
2112 | if (test_bit(__QLCNIC_START_FW, &adapter->state)) { | 2132 | if (qlcnic_api_lock(adapter)) |
2133 | goto err_ret; | ||
2113 | 2134 | ||
2114 | if (qlcnic_check_drv_state(adapter) && | 2135 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { |
2115 | (adapter->fw_wait_cnt++ < adapter->reset_ack_timeo)) { | 2136 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", |
2116 | qlcnic_schedule_work(adapter, | 2137 | adapter->reset_ack_timeo); |
2117 | qlcnic_fwinit_work, FW_POLL_DELAY); | 2138 | goto skip_ack_check; |
2118 | return; | 2139 | } |
2140 | |||
2141 | if (!qlcnic_check_drv_state(adapter)) { | ||
2142 | skip_ack_check: | ||
2143 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
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"); | ||
2119 | } | 2149 | } |
2120 | 2150 | ||
2121 | QLCDB(adapter, DRV, "Resetting FW\n"); | 2151 | qlcnic_api_unlock(adapter); |
2152 | |||
2122 | if (!qlcnic_start_firmware(adapter)) { | 2153 | if (!qlcnic_start_firmware(adapter)) { |
2123 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2154 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2124 | return; | 2155 | return; |
2125 | } | 2156 | } |
2126 | |||
2127 | goto err_ret; | 2157 | goto err_ret; |
2128 | } | 2158 | } |
2129 | 2159 | ||
2130 | if (adapter->fw_wait_cnt++ > (adapter->dev_init_timeo / 2)) { | 2160 | qlcnic_api_unlock(adapter); |
2131 | dev_err(&adapter->pdev->dev, | ||
2132 | "Waiting for device to reset timeout\n"); | ||
2133 | goto err_ret; | ||
2134 | } | ||
2135 | 2161 | ||
2136 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2162 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2137 | QLCDB(adapter, HW, "Func waiting: Device state=%d\n", dev_state); | 2163 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); |
2138 | 2164 | ||
2139 | switch (dev_state) { | 2165 | switch (dev_state) { |
2140 | case QLCNIC_DEV_READY: | 2166 | case QLCNIC_DEV_NEED_RESET: |
2141 | if (!qlcnic_start_firmware(adapter)) { | 2167 | qlcnic_schedule_work(adapter, |
2142 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2168 | qlcnic_fwinit_work, FW_POLL_DELAY); |
2143 | return; | 2169 | return; |
2144 | } | ||
2145 | case QLCNIC_DEV_FAILED: | 2170 | case QLCNIC_DEV_FAILED: |
2146 | break; | 2171 | break; |
2147 | 2172 | ||
2148 | default: | 2173 | default: |
2149 | qlcnic_schedule_work(adapter, | 2174 | if (!qlcnic_start_firmware(adapter)) { |
2150 | qlcnic_fwinit_work, 2 * FW_POLL_DELAY); | 2175 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2151 | return; | 2176 | return; |
2177 | } | ||
2152 | } | 2178 | } |
2153 | 2179 | ||
2154 | err_ret: | 2180 | err_ret: |
2181 | dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " | ||
2182 | "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); | ||
2155 | netif_device_attach(adapter->netdev); | 2183 | netif_device_attach(adapter->netdev); |
2156 | qlcnic_clr_all_drv_state(adapter); | 2184 | qlcnic_clr_all_drv_state(adapter); |
2157 | } | 2185 | } |
@@ -2180,7 +2208,8 @@ qlcnic_detach_work(struct work_struct *work) | |||
2180 | if (adapter->temp == QLCNIC_TEMP_PANIC) | 2208 | if (adapter->temp == QLCNIC_TEMP_PANIC) |
2181 | goto err_ret; | 2209 | goto err_ret; |
2182 | 2210 | ||
2183 | qlcnic_set_drv_state(adapter, adapter->dev_state); | 2211 | if (qlcnic_set_drv_state(adapter, adapter->dev_state)) |
2212 | goto err_ret; | ||
2184 | 2213 | ||
2185 | adapter->fw_wait_cnt = 0; | 2214 | adapter->fw_wait_cnt = 0; |
2186 | 2215 | ||
@@ -2196,6 +2225,7 @@ err_ret: | |||
2196 | 2225 | ||
2197 | } | 2226 | } |
2198 | 2227 | ||
2228 | /*Transit to RESET state from READY state only */ | ||
2199 | static void | 2229 | static void |
2200 | qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | 2230 | qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) |
2201 | { | 2231 | { |
@@ -2206,9 +2236,8 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | |||
2206 | 2236 | ||
2207 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2237 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2208 | 2238 | ||
2209 | if (state != QLCNIC_DEV_INITALIZING && state != QLCNIC_DEV_NEED_RESET) { | 2239 | if (state == QLCNIC_DEV_READY) { |
2210 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); | 2240 | QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_RESET); |
2211 | set_bit(__QLCNIC_START_FW, &adapter->state); | ||
2212 | QLCDB(adapter, DRV, "NEED_RESET state set\n"); | 2241 | QLCDB(adapter, DRV, "NEED_RESET state set\n"); |
2213 | } | 2242 | } |
2214 | 2243 | ||