diff options
author | Sony Chacko <sony.chacko@qlogic.com> | 2012-12-31 22:20:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-02 05:43:26 -0500 |
commit | 7e2cf4feba058476324dc545e3d1b316998c91e6 (patch) | |
tree | 438e0e76566f808b74736caa0e04316851c278f9 /drivers/net/ethernet/qlogic | |
parent | 8395be5e04647c56fa6b9cac6dfd6ae16bcb7de3 (diff) |
qlcnic: change driver hardware interface mechanism
Refactor 82xx driver to support new adapter - Qlogic 83XX CNA
Create adapter abstraction layer and seperate 82xx hardware access routines.
Create mailbox based HW interface mechanism
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 326 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 619 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 97 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 161 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 56 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 260 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 10 |
9 files changed, 1035 insertions, 518 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index bc7ec64e9c7a..5c5c57813cdd 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -402,6 +402,7 @@ struct qlcnic_hardware_context { | |||
402 | struct qlcnic_hardware_ops *hw_ops; | 402 | struct qlcnic_hardware_ops *hw_ops; |
403 | struct qlcnic_nic_intr_coalesce coal; | 403 | struct qlcnic_nic_intr_coalesce coal; |
404 | struct qlcnic_fw_dump fw_dump; | 404 | struct qlcnic_fw_dump fw_dump; |
405 | u32 *reg_tbl; | ||
405 | }; | 406 | }; |
406 | 407 | ||
407 | struct qlcnic_adapter_stats { | 408 | struct qlcnic_adapter_stats { |
@@ -492,8 +493,6 @@ struct qlcnic_recv_context { | |||
492 | /* HW context creation */ | 493 | /* HW context creation */ |
493 | 494 | ||
494 | #define QLCNIC_OS_CRB_RETRY_COUNT 4000 | 495 | #define QLCNIC_OS_CRB_RETRY_COUNT 4000 |
495 | #define QLCNIC_CDRP_SIGNATURE_MAKE(pcifn, version) \ | ||
496 | (((pcifn) & 0xff) | (((version) & 0xff) << 8) | (0xcafe << 16)) | ||
497 | 496 | ||
498 | #define QLCNIC_CDRP_CMD_BIT 0x80000000 | 497 | #define QLCNIC_CDRP_CMD_BIT 0x80000000 |
499 | 498 | ||
@@ -1266,10 +1265,8 @@ struct qlcnic_esw_statistics { | |||
1266 | #define QLCNIC_RESET_QUIESCENT 0xadd00020 | 1265 | #define QLCNIC_RESET_QUIESCENT 0xadd00020 |
1267 | 1266 | ||
1268 | struct _cdrp_cmd { | 1267 | struct _cdrp_cmd { |
1269 | u32 cmd; | 1268 | u32 num; |
1270 | u32 arg1; | 1269 | u32 *arg; |
1271 | u32 arg2; | ||
1272 | u32 arg3; | ||
1273 | }; | 1270 | }; |
1274 | 1271 | ||
1275 | struct qlcnic_cmd_args { | 1272 | struct qlcnic_cmd_args { |
@@ -1279,9 +1276,6 @@ struct qlcnic_cmd_args { | |||
1279 | 1276 | ||
1280 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter); | 1277 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter); |
1281 | int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config); | 1278 | int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config); |
1282 | |||
1283 | int qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off); | ||
1284 | int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data); | ||
1285 | int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data); | 1279 | int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data); |
1286 | int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data); | 1280 | int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data); |
1287 | void qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *, u64, u64 *); | 1281 | void qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *, u64, u64 *); |
@@ -1291,9 +1285,10 @@ void qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *, u64, u64); | |||
1291 | (((addr) < (high)) && ((addr) >= (low))) | 1285 | (((addr) < (high)) && ((addr) >= (low))) |
1292 | 1286 | ||
1293 | #define QLCRD32(adapter, off) \ | 1287 | #define QLCRD32(adapter, off) \ |
1294 | (qlcnic_hw_read_wx_2M(adapter, off)) | 1288 | (adapter->ahw->hw_ops->read_reg)(adapter, off) |
1289 | |||
1295 | #define QLCWR32(adapter, off, val) \ | 1290 | #define QLCWR32(adapter, off, val) \ |
1296 | (qlcnic_hw_write_wx_2M(adapter, off, val)) | 1291 | adapter->ahw->hw_ops->write_reg(adapter, off, val) |
1297 | 1292 | ||
1298 | int qlcnic_pcie_sem_lock(struct qlcnic_adapter *, int, u32); | 1293 | int qlcnic_pcie_sem_lock(struct qlcnic_adapter *, int, u32); |
1299 | void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int); | 1294 | void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int); |
@@ -1306,10 +1301,6 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int); | |||
1306 | qlcnic_pcie_sem_lock((a), 3, QLCNIC_PHY_LOCK_ID) | 1301 | qlcnic_pcie_sem_lock((a), 3, QLCNIC_PHY_LOCK_ID) |
1307 | #define qlcnic_phy_unlock(a) \ | 1302 | #define qlcnic_phy_unlock(a) \ |
1308 | qlcnic_pcie_sem_unlock((a), 3) | 1303 | qlcnic_pcie_sem_unlock((a), 3) |
1309 | #define qlcnic_api_lock(a) \ | ||
1310 | qlcnic_pcie_sem_lock((a), 5, 0) | ||
1311 | #define qlcnic_api_unlock(a) \ | ||
1312 | qlcnic_pcie_sem_unlock((a), 5) | ||
1313 | #define qlcnic_sw_lock(a) \ | 1304 | #define qlcnic_sw_lock(a) \ |
1314 | qlcnic_pcie_sem_lock((a), 6, 0) | 1305 | qlcnic_pcie_sem_lock((a), 6, 0) |
1315 | #define qlcnic_sw_unlock(a) \ | 1306 | #define qlcnic_sw_unlock(a) \ |
@@ -1324,9 +1315,7 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int); | |||
1324 | 1315 | ||
1325 | #define MAX_CTL_CHECK 1000 | 1316 | #define MAX_CTL_CHECK 1000 |
1326 | 1317 | ||
1327 | int qlcnic_get_board_info(struct qlcnic_adapter *adapter); | ||
1328 | int qlcnic_wol_supported(struct qlcnic_adapter *adapter); | 1318 | int qlcnic_wol_supported(struct qlcnic_adapter *adapter); |
1329 | int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate); | ||
1330 | void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter); | 1319 | void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter); |
1331 | void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter); | 1320 | void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter); |
1332 | int qlcnic_dump_fw(struct qlcnic_adapter *); | 1321 | int qlcnic_dump_fw(struct qlcnic_adapter *); |
@@ -1365,47 +1354,28 @@ void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, | |||
1365 | int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max); | 1354 | int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max); |
1366 | void qlcnic_set_multi(struct net_device *netdev); | 1355 | void qlcnic_set_multi(struct net_device *netdev); |
1367 | void qlcnic_free_mac_list(struct qlcnic_adapter *adapter); | 1356 | void qlcnic_free_mac_list(struct qlcnic_adapter *adapter); |
1368 | int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32); | ||
1369 | int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter); | ||
1370 | int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable); | ||
1371 | int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd); | ||
1372 | int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable); | ||
1373 | void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup); | ||
1374 | 1357 | ||
1375 | int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); | 1358 | int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); |
1376 | int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); | 1359 | int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); |
1377 | netdev_features_t qlcnic_fix_features(struct net_device *netdev, | 1360 | netdev_features_t qlcnic_fix_features(struct net_device *netdev, |
1378 | netdev_features_t features); | 1361 | netdev_features_t features); |
1379 | int qlcnic_set_features(struct net_device *netdev, netdev_features_t features); | 1362 | int qlcnic_set_features(struct net_device *netdev, netdev_features_t features); |
1380 | int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable); | ||
1381 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); | 1363 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); |
1382 | int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); | 1364 | int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); |
1383 | void qlcnic_update_cmd_producer(struct qlcnic_host_tx_ring *); | 1365 | void qlcnic_update_cmd_producer(struct qlcnic_host_tx_ring *); |
1384 | void qlcnic_fetch_mac(u32, u32, u8, u8 *); | ||
1385 | void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); | ||
1386 | void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter); | ||
1387 | int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode); | ||
1388 | 1366 | ||
1389 | /* Functions from qlcnic_ethtool.c */ | 1367 | /* Functions from qlcnic_ethtool.c */ |
1390 | int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]); | 1368 | int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]); |
1391 | 1369 | ||
1392 | /* Functions from qlcnic_main.c */ | 1370 | /* Functions from qlcnic_main.c */ |
1393 | int qlcnic_reset_context(struct qlcnic_adapter *); | 1371 | int qlcnic_reset_context(struct qlcnic_adapter *); |
1394 | void qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *); | ||
1395 | void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); | 1372 | void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); |
1396 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test); | 1373 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test); |
1397 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 1374 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
1398 | int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val); | ||
1399 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data); | 1375 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data); |
1400 | void qlcnic_dev_request_reset(struct qlcnic_adapter *); | 1376 | int qlcnic_validate_max_rss(struct net_device *netdev, u8, u8); |
1401 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); | 1377 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); |
1402 | 1378 | ||
1403 | /* Management functions */ | ||
1404 | int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); | ||
1405 | int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8); | ||
1406 | int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); | ||
1407 | int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*); | ||
1408 | |||
1409 | /* eSwitch management functions */ | 1379 | /* eSwitch management functions */ |
1410 | int qlcnic_config_switch_port(struct qlcnic_adapter *, | 1380 | int qlcnic_config_switch_port(struct qlcnic_adapter *, |
1411 | struct qlcnic_esw_func_cfg *); | 1381 | struct qlcnic_esw_func_cfg *); |
@@ -1418,12 +1388,10 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8, | |||
1418 | struct __qlcnic_esw_statistics *); | 1388 | struct __qlcnic_esw_statistics *); |
1419 | int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8); | 1389 | int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8); |
1420 | int qlcnic_get_mac_stats(struct qlcnic_adapter *, struct qlcnic_mac_statistics *); | 1390 | int qlcnic_get_mac_stats(struct qlcnic_adapter *, struct qlcnic_mac_statistics *); |
1421 | extern int qlcnic_config_tso; | ||
1422 | 1391 | ||
1423 | int qlcnic_napi_add(struct qlcnic_adapter *, struct net_device *); | 1392 | void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd); |
1424 | void qlcnic_napi_del(struct qlcnic_adapter *adapter); | 1393 | void qlcnic_napi_del(struct qlcnic_adapter *); |
1425 | void qlcnic_napi_enable(struct qlcnic_adapter *adapter); | 1394 | |
1426 | void qlcnic_napi_disable(struct qlcnic_adapter *adapter); | ||
1427 | int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *, int); | 1395 | int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *, int); |
1428 | void qlcnic_free_sds_rings(struct qlcnic_recv_context *); | 1396 | void qlcnic_free_sds_rings(struct qlcnic_recv_context *); |
1429 | void qlcnic_free_tx_rings(struct qlcnic_adapter *); | 1397 | void qlcnic_free_tx_rings(struct qlcnic_adapter *); |
@@ -1433,6 +1401,9 @@ void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter); | |||
1433 | void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter); | 1401 | void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter); |
1434 | void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); | 1402 | void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); |
1435 | void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); | 1403 | void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); |
1404 | void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter); | ||
1405 | void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter); | ||
1406 | |||
1436 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); | 1407 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); |
1437 | int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); | 1408 | int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); |
1438 | void qlcnic_set_vlan_config(struct qlcnic_adapter *, | 1409 | void qlcnic_set_vlan_config(struct qlcnic_adapter *, |
@@ -1462,6 +1433,271 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring) | |||
1462 | tx_ring->producer; | 1433 | tx_ring->producer; |
1463 | } | 1434 | } |
1464 | 1435 | ||
1436 | struct qlcnic_nic_template { | ||
1437 | int (*config_bridged_mode) (struct qlcnic_adapter *, u32); | ||
1438 | int (*config_led) (struct qlcnic_adapter *, u32, u32); | ||
1439 | int (*start_firmware) (struct qlcnic_adapter *); | ||
1440 | int (*init_driver) (struct qlcnic_adapter *); | ||
1441 | void (*request_reset) (struct qlcnic_adapter *, u32); | ||
1442 | void (*cancel_idc_work) (struct qlcnic_adapter *); | ||
1443 | int (*napi_add)(struct qlcnic_adapter *, struct net_device *); | ||
1444 | void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int); | ||
1445 | irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *); | ||
1446 | }; | ||
1447 | |||
1448 | /* Adapter hardware abstraction */ | ||
1449 | struct qlcnic_hardware_ops { | ||
1450 | void (*read_crb) (struct qlcnic_adapter *, char *, loff_t, size_t); | ||
1451 | void (*write_crb) (struct qlcnic_adapter *, char *, loff_t, size_t); | ||
1452 | int (*read_reg) (struct qlcnic_adapter *, ulong); | ||
1453 | int (*write_reg) (struct qlcnic_adapter *, ulong, u32); | ||
1454 | void (*get_ocm_win) (struct qlcnic_hardware_context *); | ||
1455 | int (*get_mac_address) (struct qlcnic_adapter *, u8 *); | ||
1456 | int (*setup_intr) (struct qlcnic_adapter *, u8); | ||
1457 | int (*alloc_mbx_args)(struct qlcnic_cmd_args *, | ||
1458 | struct qlcnic_adapter *, u32); | ||
1459 | int (*mbx_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *); | ||
1460 | void (*get_func_no) (struct qlcnic_adapter *); | ||
1461 | int (*api_lock) (struct qlcnic_adapter *); | ||
1462 | void (*api_unlock) (struct qlcnic_adapter *); | ||
1463 | void (*add_sysfs) (struct qlcnic_adapter *); | ||
1464 | void (*remove_sysfs) (struct qlcnic_adapter *); | ||
1465 | void (*process_lb_rcv_ring_diag) (struct qlcnic_host_sds_ring *); | ||
1466 | int (*create_rx_ctx) (struct qlcnic_adapter *); | ||
1467 | int (*create_tx_ctx) (struct qlcnic_adapter *, | ||
1468 | struct qlcnic_host_tx_ring *, int); | ||
1469 | int (*setup_link_event) (struct qlcnic_adapter *, int); | ||
1470 | int (*get_nic_info) (struct qlcnic_adapter *, struct qlcnic_info *, u8); | ||
1471 | int (*get_pci_info) (struct qlcnic_adapter *, struct qlcnic_pci_info *); | ||
1472 | int (*set_nic_info) (struct qlcnic_adapter *, struct qlcnic_info *); | ||
1473 | int (*change_macvlan) (struct qlcnic_adapter *, u8*, __le16, u8); | ||
1474 | void (*napi_enable) (struct qlcnic_adapter *); | ||
1475 | void (*napi_disable) (struct qlcnic_adapter *); | ||
1476 | void (*config_intr_coal) (struct qlcnic_adapter *); | ||
1477 | int (*config_rss) (struct qlcnic_adapter *, int); | ||
1478 | int (*config_hw_lro) (struct qlcnic_adapter *, int); | ||
1479 | int (*config_loopback) (struct qlcnic_adapter *, u8); | ||
1480 | int (*clear_loopback) (struct qlcnic_adapter *, u8); | ||
1481 | int (*config_promisc_mode) (struct qlcnic_adapter *, u32); | ||
1482 | void (*change_l2_filter) (struct qlcnic_adapter *, u64 *, __le16); | ||
1483 | int (*get_board_info) (struct qlcnic_adapter *); | ||
1484 | }; | ||
1485 | |||
1486 | extern struct qlcnic_nic_template qlcnic_vf_ops; | ||
1487 | |||
1488 | static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter) | ||
1489 | { | ||
1490 | return adapter->nic_ops->start_firmware(adapter); | ||
1491 | } | ||
1492 | |||
1493 | static inline void qlcnic_read_crb(struct qlcnic_adapter *adapter, char *buf, | ||
1494 | loff_t offset, size_t size) | ||
1495 | { | ||
1496 | adapter->ahw->hw_ops->read_crb(adapter, buf, offset, size); | ||
1497 | } | ||
1498 | |||
1499 | static inline void qlcnic_write_crb(struct qlcnic_adapter *adapter, char *buf, | ||
1500 | loff_t offset, size_t size) | ||
1501 | { | ||
1502 | adapter->ahw->hw_ops->write_crb(adapter, buf, offset, size); | ||
1503 | } | ||
1504 | |||
1505 | static inline u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, | ||
1506 | ulong off) | ||
1507 | { | ||
1508 | return adapter->ahw->hw_ops->read_reg(adapter, off); | ||
1509 | } | ||
1510 | |||
1511 | static inline int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, | ||
1512 | ulong off, u32 data) | ||
1513 | { | ||
1514 | return adapter->ahw->hw_ops->write_reg(adapter, off, data); | ||
1515 | } | ||
1516 | |||
1517 | static inline int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, | ||
1518 | u8 *mac) | ||
1519 | { | ||
1520 | return adapter->ahw->hw_ops->get_mac_address(adapter, mac); | ||
1521 | } | ||
1522 | |||
1523 | static inline int qlcnic_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) | ||
1524 | { | ||
1525 | return adapter->ahw->hw_ops->setup_intr(adapter, num_intr); | ||
1526 | } | ||
1527 | |||
1528 | static inline int qlcnic_alloc_mbx_args(struct qlcnic_cmd_args *mbx, | ||
1529 | struct qlcnic_adapter *adapter, u32 arg) | ||
1530 | { | ||
1531 | return adapter->ahw->hw_ops->alloc_mbx_args(mbx, adapter, arg); | ||
1532 | } | ||
1533 | |||
1534 | static inline int qlcnic_issue_cmd(struct qlcnic_adapter *adapter, | ||
1535 | struct qlcnic_cmd_args *cmd) | ||
1536 | { | ||
1537 | return adapter->ahw->hw_ops->mbx_cmd(adapter, cmd); | ||
1538 | } | ||
1539 | |||
1540 | static inline void qlcnic_get_func_no(struct qlcnic_adapter *adapter) | ||
1541 | { | ||
1542 | adapter->ahw->hw_ops->get_func_no(adapter); | ||
1543 | } | ||
1544 | |||
1545 | static inline int qlcnic_api_lock(struct qlcnic_adapter *adapter) | ||
1546 | { | ||
1547 | return adapter->ahw->hw_ops->api_lock(adapter); | ||
1548 | } | ||
1549 | |||
1550 | static inline void qlcnic_api_unlock(struct qlcnic_adapter *adapter) | ||
1551 | { | ||
1552 | adapter->ahw->hw_ops->api_unlock(adapter); | ||
1553 | } | ||
1554 | |||
1555 | static inline void qlcnic_add_sysfs(struct qlcnic_adapter *adapter) | ||
1556 | { | ||
1557 | adapter->ahw->hw_ops->add_sysfs(adapter); | ||
1558 | } | ||
1559 | |||
1560 | static inline void qlcnic_remove_sysfs(struct qlcnic_adapter *adapter) | ||
1561 | { | ||
1562 | adapter->ahw->hw_ops->remove_sysfs(adapter); | ||
1563 | } | ||
1564 | |||
1565 | static inline void | ||
1566 | qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) | ||
1567 | { | ||
1568 | sds_ring->adapter->ahw->hw_ops->process_lb_rcv_ring_diag(sds_ring); | ||
1569 | } | ||
1570 | |||
1571 | static inline int qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | ||
1572 | { | ||
1573 | return adapter->ahw->hw_ops->create_rx_ctx(adapter); | ||
1574 | } | ||
1575 | |||
1576 | static inline int qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter, | ||
1577 | struct qlcnic_host_tx_ring *ptr, | ||
1578 | int ring) | ||
1579 | { | ||
1580 | return adapter->ahw->hw_ops->create_tx_ctx(adapter, ptr, ring); | ||
1581 | } | ||
1582 | |||
1583 | static inline int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, | ||
1584 | int enable) | ||
1585 | { | ||
1586 | return adapter->ahw->hw_ops->setup_link_event(adapter, enable); | ||
1587 | } | ||
1588 | |||
1589 | static inline int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, | ||
1590 | struct qlcnic_info *info, u8 id) | ||
1591 | { | ||
1592 | return adapter->ahw->hw_ops->get_nic_info(adapter, info, id); | ||
1593 | } | ||
1594 | |||
1595 | static inline int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, | ||
1596 | struct qlcnic_pci_info *info) | ||
1597 | { | ||
1598 | return adapter->ahw->hw_ops->get_pci_info(adapter, info); | ||
1599 | } | ||
1600 | |||
1601 | static inline int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, | ||
1602 | struct qlcnic_info *info) | ||
1603 | { | ||
1604 | return adapter->ahw->hw_ops->set_nic_info(adapter, info); | ||
1605 | } | ||
1606 | |||
1607 | static inline int qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, | ||
1608 | u8 *addr, __le16 id, u8 cmd) | ||
1609 | { | ||
1610 | return adapter->ahw->hw_ops->change_macvlan(adapter, addr, id, cmd); | ||
1611 | } | ||
1612 | |||
1613 | static inline int qlcnic_napi_add(struct qlcnic_adapter *adapter, | ||
1614 | struct net_device *netdev) | ||
1615 | { | ||
1616 | return adapter->nic_ops->napi_add(adapter, netdev); | ||
1617 | } | ||
1618 | |||
1619 | static inline void qlcnic_napi_enable(struct qlcnic_adapter *adapter) | ||
1620 | { | ||
1621 | adapter->ahw->hw_ops->napi_enable(adapter); | ||
1622 | } | ||
1623 | |||
1624 | static inline void qlcnic_napi_disable(struct qlcnic_adapter *adapter) | ||
1625 | { | ||
1626 | adapter->ahw->hw_ops->napi_disable(adapter); | ||
1627 | } | ||
1628 | |||
1629 | static inline void qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) | ||
1630 | { | ||
1631 | adapter->ahw->hw_ops->config_intr_coal(adapter); | ||
1632 | } | ||
1633 | |||
1634 | static inline int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) | ||
1635 | { | ||
1636 | return adapter->ahw->hw_ops->config_rss(adapter, enable); | ||
1637 | } | ||
1638 | |||
1639 | static inline int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, | ||
1640 | int enable) | ||
1641 | { | ||
1642 | return adapter->ahw->hw_ops->config_hw_lro(adapter, enable); | ||
1643 | } | ||
1644 | |||
1645 | static inline int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) | ||
1646 | { | ||
1647 | return adapter->ahw->hw_ops->config_loopback(adapter, mode); | ||
1648 | } | ||
1649 | |||
1650 | static inline int qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode) | ||
1651 | { | ||
1652 | return adapter->ahw->hw_ops->config_loopback(adapter, mode); | ||
1653 | } | ||
1654 | |||
1655 | static inline int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, | ||
1656 | u32 mode) | ||
1657 | { | ||
1658 | return adapter->ahw->hw_ops->config_promisc_mode(adapter, mode); | ||
1659 | } | ||
1660 | |||
1661 | static inline void qlcnic_change_filter(struct qlcnic_adapter *adapter, | ||
1662 | u64 *addr, __le16 id) | ||
1663 | { | ||
1664 | adapter->ahw->hw_ops->change_l2_filter(adapter, addr, id); | ||
1665 | } | ||
1666 | |||
1667 | static inline int qlcnic_get_board_info(struct qlcnic_adapter *adapter) | ||
1668 | { | ||
1669 | return adapter->ahw->hw_ops->get_board_info(adapter); | ||
1670 | } | ||
1671 | |||
1672 | static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter, | ||
1673 | u32 key) | ||
1674 | { | ||
1675 | adapter->nic_ops->request_reset(adapter, key); | ||
1676 | } | ||
1677 | |||
1678 | static inline void qlcnic_cancel_idc_work(struct qlcnic_adapter *adapter) | ||
1679 | { | ||
1680 | adapter->nic_ops->cancel_idc_work(adapter); | ||
1681 | } | ||
1682 | |||
1683 | static inline irqreturn_t | ||
1684 | qlcnic_clear_legacy_intr(struct qlcnic_adapter *adapter) | ||
1685 | { | ||
1686 | return adapter->nic_ops->clear_legacy_intr(adapter); | ||
1687 | } | ||
1688 | |||
1689 | static inline int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, | ||
1690 | u32 rate) | ||
1691 | { | ||
1692 | return adapter->nic_ops->config_led(adapter, state, rate); | ||
1693 | } | ||
1694 | |||
1695 | static inline void qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, | ||
1696 | __be32 ip, int cmd) | ||
1697 | { | ||
1698 | adapter->nic_ops->config_ipaddr(adapter, ip, cmd); | ||
1699 | } | ||
1700 | |||
1465 | static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring) | 1701 | static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring) |
1466 | { | 1702 | { |
1467 | writel(0, sds_ring->crb_intr_mask); | 1703 | writel(0, sds_ring->crb_intr_mask); |
@@ -1480,12 +1716,6 @@ static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring) | |||
1480 | extern const struct ethtool_ops qlcnic_ethtool_ops; | 1716 | extern const struct ethtool_ops qlcnic_ethtool_ops; |
1481 | extern const struct ethtool_ops qlcnic_ethtool_failed_ops; | 1717 | extern const struct ethtool_ops qlcnic_ethtool_failed_ops; |
1482 | 1718 | ||
1483 | struct qlcnic_nic_template { | ||
1484 | int (*config_bridged_mode) (struct qlcnic_adapter *, u32); | ||
1485 | int (*config_led) (struct qlcnic_adapter *, u32, u32); | ||
1486 | int (*start_firmware) (struct qlcnic_adapter *); | ||
1487 | }; | ||
1488 | |||
1489 | #define QLCDB(adapter, lvl, _fmt, _args...) do { \ | 1719 | #define QLCDB(adapter, lvl, _fmt, _args...) do { \ |
1490 | if (NETIF_MSG_##lvl & adapter->ahw->msg_enable) \ | 1720 | if (NETIF_MSG_##lvl & adapter->ahw->msg_enable) \ |
1491 | printk(KERN_INFO "%s: %s: " _fmt, \ | 1721 | printk(KERN_INFO "%s: %s: " _fmt, \ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index b14b8f0787ea..7ebd8612d4cb 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |||
@@ -7,6 +7,86 @@ | |||
7 | 7 | ||
8 | #include "qlcnic.h" | 8 | #include "qlcnic.h" |
9 | 9 | ||
10 | static const struct qlcnic_mailbox_metadata qlcnic_mbx_tbl[] = { | ||
11 | {QLCNIC_CMD_CREATE_RX_CTX, 4, 1}, | ||
12 | {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1}, | ||
13 | {QLCNIC_CMD_CREATE_TX_CTX, 4, 1}, | ||
14 | {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1}, | ||
15 | {QLCNIC_CMD_INTRPT_TEST, 4, 1}, | ||
16 | {QLCNIC_CMD_SET_MTU, 4, 1}, | ||
17 | {QLCNIC_CMD_READ_PHY, 4, 2}, | ||
18 | {QLCNIC_CMD_WRITE_PHY, 5, 1}, | ||
19 | {QLCNIC_CMD_READ_HW_REG, 4, 1}, | ||
20 | {QLCNIC_CMD_GET_FLOW_CTL, 4, 2}, | ||
21 | {QLCNIC_CMD_SET_FLOW_CTL, 4, 1}, | ||
22 | {QLCNIC_CMD_READ_MAX_MTU, 4, 2}, | ||
23 | {QLCNIC_CMD_READ_MAX_LRO, 4, 2}, | ||
24 | {QLCNIC_CMD_MAC_ADDRESS, 4, 3}, | ||
25 | {QLCNIC_CMD_GET_PCI_INFO, 4, 1}, | ||
26 | {QLCNIC_CMD_GET_NIC_INFO, 4, 1}, | ||
27 | {QLCNIC_CMD_SET_NIC_INFO, 4, 1}, | ||
28 | {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3}, | ||
29 | {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1}, | ||
30 | {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3}, | ||
31 | {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1}, | ||
32 | {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1}, | ||
33 | {QLCNIC_CMD_GET_MAC_STATS, 4, 1}, | ||
34 | {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3}, | ||
35 | {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1}, | ||
36 | {QLCNIC_CMD_CONFIG_PORT, 4, 1}, | ||
37 | {QLCNIC_CMD_TEMP_SIZE, 4, 4}, | ||
38 | {QLCNIC_CMD_GET_TEMP_HDR, 4, 1}, | ||
39 | {QLCNIC_CMD_SET_DRV_VER, 4, 1}, | ||
40 | }; | ||
41 | |||
42 | static inline u32 qlcnic_get_cmd_signature(struct qlcnic_hardware_context *ahw) | ||
43 | { | ||
44 | return (ahw->pci_func & 0xff) | ((ahw->fw_hal_version & 0xff) << 8) | | ||
45 | (0xcafe << 16); | ||
46 | } | ||
47 | |||
48 | /* Allocate mailbox registers */ | ||
49 | int qlcnic_82xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx, | ||
50 | struct qlcnic_adapter *adapter, u32 type) | ||
51 | { | ||
52 | int i, size; | ||
53 | const struct qlcnic_mailbox_metadata *mbx_tbl; | ||
54 | |||
55 | mbx_tbl = qlcnic_mbx_tbl; | ||
56 | size = ARRAY_SIZE(qlcnic_mbx_tbl); | ||
57 | for (i = 0; i < size; i++) { | ||
58 | if (type == mbx_tbl[i].cmd) { | ||
59 | mbx->req.num = mbx_tbl[i].in_args; | ||
60 | mbx->rsp.num = mbx_tbl[i].out_args; | ||
61 | mbx->req.arg = kcalloc(mbx->req.num, | ||
62 | sizeof(u32), GFP_ATOMIC); | ||
63 | if (!mbx->req.arg) | ||
64 | return -ENOMEM; | ||
65 | mbx->rsp.arg = kcalloc(mbx->rsp.num, | ||
66 | sizeof(u32), GFP_ATOMIC); | ||
67 | if (!mbx->rsp.arg) { | ||
68 | kfree(mbx->req.arg); | ||
69 | mbx->req.arg = NULL; | ||
70 | return -ENOMEM; | ||
71 | } | ||
72 | memset(mbx->req.arg, 0, sizeof(u32) * mbx->req.num); | ||
73 | memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num); | ||
74 | mbx->req.arg[0] = type; | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | /* Free up mailbox registers */ | ||
82 | void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd) | ||
83 | { | ||
84 | kfree(cmd->req.arg); | ||
85 | cmd->req.arg = NULL; | ||
86 | kfree(cmd->rsp.arg); | ||
87 | cmd->rsp.arg = NULL; | ||
88 | } | ||
89 | |||
10 | static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | 90 | static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) |
11 | { | 91 | { |
12 | int i; | 92 | int i; |
@@ -38,194 +118,105 @@ qlcnic_poll_rsp(struct qlcnic_adapter *adapter) | |||
38 | return rsp; | 118 | return rsp; |
39 | } | 119 | } |
40 | 120 | ||
41 | void | 121 | int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter, |
42 | qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd) | 122 | struct qlcnic_cmd_args *cmd) |
43 | { | 123 | { |
124 | int i; | ||
44 | u32 rsp; | 125 | u32 rsp; |
45 | u32 signature; | 126 | u32 signature; |
46 | struct pci_dev *pdev = adapter->pdev; | 127 | struct pci_dev *pdev = adapter->pdev; |
47 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 128 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
48 | 129 | ||
49 | signature = QLCNIC_CDRP_SIGNATURE_MAKE(ahw->pci_func, | 130 | signature = qlcnic_get_cmd_signature(ahw); |
50 | adapter->ahw->fw_hal_version); | ||
51 | 131 | ||
52 | /* Acquire semaphore before accessing CRB */ | 132 | /* Acquire semaphore before accessing CRB */ |
53 | if (qlcnic_api_lock(adapter)) { | 133 | if (qlcnic_api_lock(adapter)) { |
54 | cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT; | 134 | cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT; |
55 | return; | 135 | return cmd->rsp.arg[0]; |
56 | } | 136 | } |
57 | 137 | ||
58 | QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature); | 138 | QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature); |
59 | QLCWR32(adapter, QLCNIC_ARG1_CRB_OFFSET, cmd->req.arg1); | 139 | for (i = 1; i < QLCNIC_CDRP_MAX_ARGS; i++) |
60 | QLCWR32(adapter, QLCNIC_ARG2_CRB_OFFSET, cmd->req.arg2); | 140 | QLCWR32(adapter, QLCNIC_CDRP_ARG(i), cmd->req.arg[i]); |
61 | QLCWR32(adapter, QLCNIC_ARG3_CRB_OFFSET, cmd->req.arg3); | ||
62 | QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET, | 141 | QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET, |
63 | QLCNIC_CDRP_FORM_CMD(cmd->req.cmd)); | 142 | QLCNIC_CDRP_FORM_CMD(cmd->req.arg[0])); |
64 | |||
65 | rsp = qlcnic_poll_rsp(adapter); | 143 | rsp = qlcnic_poll_rsp(adapter); |
66 | 144 | ||
67 | if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { | 145 | if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { |
68 | dev_err(&pdev->dev, "CDRP response timeout.\n"); | 146 | dev_err(&pdev->dev, "card response timeout.\n"); |
69 | cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT; | 147 | cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT; |
70 | } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { | 148 | } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { |
71 | cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); | 149 | cmd->rsp.arg[0] = QLCRD32(adapter, QLCNIC_CDRP_ARG(1)); |
72 | switch (cmd->rsp.cmd) { | 150 | dev_err(&pdev->dev, "failed card response code:0x%x\n", |
73 | case QLCNIC_RCODE_INVALID_ARGS: | 151 | cmd->rsp.arg[0]); |
74 | dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n", | 152 | } else if (rsp == QLCNIC_CDRP_RSP_OK) |
75 | cmd->rsp.cmd); | 153 | cmd->rsp.arg[0] = QLCNIC_RCODE_SUCCESS; |
76 | break; | 154 | |
77 | case QLCNIC_RCODE_NOT_SUPPORTED: | 155 | for (i = 1; i < cmd->rsp.num; i++) |
78 | case QLCNIC_RCODE_NOT_IMPL: | 156 | cmd->rsp.arg[i] = QLCRD32(adapter, QLCNIC_CDRP_ARG(i)); |
79 | dev_err(&pdev->dev, | ||
80 | "CDRP command not supported: 0x%x.\n", | ||
81 | cmd->rsp.cmd); | ||
82 | break; | ||
83 | case QLCNIC_RCODE_NOT_PERMITTED: | ||
84 | dev_err(&pdev->dev, | ||
85 | "CDRP requested action not permitted: 0x%x.\n", | ||
86 | cmd->rsp.cmd); | ||
87 | break; | ||
88 | case QLCNIC_RCODE_INVALID: | ||
89 | dev_err(&pdev->dev, | ||
90 | "CDRP invalid or unknown cmd received: 0x%x.\n", | ||
91 | cmd->rsp.cmd); | ||
92 | break; | ||
93 | case QLCNIC_RCODE_TIMEOUT: | ||
94 | dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n", | ||
95 | cmd->rsp.cmd); | ||
96 | break; | ||
97 | default: | ||
98 | dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n", | ||
99 | cmd->rsp.cmd); | ||
100 | } | ||
101 | } else if (rsp == QLCNIC_CDRP_RSP_OK) { | ||
102 | cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS; | ||
103 | if (cmd->rsp.arg2) | ||
104 | cmd->rsp.arg2 = QLCRD32(adapter, | ||
105 | QLCNIC_ARG2_CRB_OFFSET); | ||
106 | if (cmd->rsp.arg3) | ||
107 | cmd->rsp.arg3 = QLCRD32(adapter, | ||
108 | QLCNIC_ARG3_CRB_OFFSET); | ||
109 | } | ||
110 | if (cmd->rsp.arg1) | ||
111 | cmd->rsp.arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); | ||
112 | 157 | ||
113 | /* Release semaphore */ | 158 | /* Release semaphore */ |
114 | qlcnic_api_unlock(adapter); | 159 | qlcnic_api_unlock(adapter); |
115 | 160 | return cmd->rsp.arg[0]; | |
116 | } | ||
117 | |||
118 | static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u32 temp_size) | ||
119 | { | ||
120 | uint64_t sum = 0; | ||
121 | int count = temp_size / sizeof(uint32_t); | ||
122 | while (count-- > 0) | ||
123 | sum += *temp_buffer++; | ||
124 | while (sum >> 32) | ||
125 | sum = (sum & 0xFFFFFFFF) + (sum >> 32); | ||
126 | return ~sum; | ||
127 | } | 161 | } |
128 | 162 | ||
129 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) | 163 | int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter) |
130 | { | 164 | { |
131 | int err, i; | 165 | int err = 0; |
132 | void *tmp_addr; | 166 | void *tmp_addr; |
133 | u32 temp_size, version, csum, *template; | ||
134 | __le32 *tmp_buf; | ||
135 | struct qlcnic_cmd_args cmd; | 167 | struct qlcnic_cmd_args cmd; |
136 | struct qlcnic_hardware_context *ahw; | ||
137 | struct qlcnic_dump_template_hdr *tmpl_hdr; | ||
138 | dma_addr_t tmp_addr_t = 0; | 168 | dma_addr_t tmp_addr_t = 0; |
139 | 169 | ||
140 | ahw = adapter->ahw; | 170 | tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, 0x1000, |
141 | memset(&cmd, 0, sizeof(cmd)); | 171 | &tmp_addr_t, GFP_KERNEL); |
142 | cmd.req.cmd = QLCNIC_CDRP_CMD_TEMP_SIZE; | ||
143 | memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd)); | ||
144 | qlcnic_issue_cmd(adapter, &cmd); | ||
145 | if (cmd.rsp.cmd != QLCNIC_RCODE_SUCCESS) { | ||
146 | dev_info(&adapter->pdev->dev, | ||
147 | "Can't get template size %d\n", cmd.rsp.cmd); | ||
148 | err = -EIO; | ||
149 | return err; | ||
150 | } | ||
151 | temp_size = cmd.rsp.arg2; | ||
152 | version = cmd.rsp.arg3; | ||
153 | dev_info(&adapter->pdev->dev, | ||
154 | "minidump template version = 0x%x", version); | ||
155 | if (!temp_size) | ||
156 | return -EIO; | ||
157 | |||
158 | tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, temp_size, | ||
159 | &tmp_addr_t, GFP_KERNEL); | ||
160 | if (!tmp_addr) { | 172 | if (!tmp_addr) { |
161 | dev_err(&adapter->pdev->dev, | 173 | dev_err(&adapter->pdev->dev, |
162 | "Can't get memory for FW dump template\n"); | 174 | "Can't get memory for FW dump template\n"); |
163 | return -ENOMEM; | 175 | return -ENOMEM; |
164 | } | 176 | } |
165 | memset(&cmd.rsp, 0, sizeof(struct _cdrp_cmd)); | ||
166 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_TEMP_HDR; | ||
167 | cmd.req.arg1 = LSD(tmp_addr_t); | ||
168 | cmd.req.arg2 = MSD(tmp_addr_t); | ||
169 | cmd.req.arg3 = temp_size; | ||
170 | qlcnic_issue_cmd(adapter, &cmd); | ||
171 | |||
172 | err = cmd.rsp.cmd; | ||
173 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
174 | dev_err(&adapter->pdev->dev, | ||
175 | "Failed to get mini dump template header %d\n", err); | ||
176 | err = -EIO; | ||
177 | goto error; | ||
178 | } | ||
179 | ahw->fw_dump.tmpl_hdr = vzalloc(temp_size); | ||
180 | if (!ahw->fw_dump.tmpl_hdr) { | ||
181 | err = -EIO; | ||
182 | goto error; | ||
183 | } | ||
184 | tmp_buf = tmp_addr; | ||
185 | template = (u32 *) ahw->fw_dump.tmpl_hdr; | ||
186 | for (i = 0; i < temp_size/sizeof(u32); i++) | ||
187 | *template++ = __le32_to_cpu(*tmp_buf++); | ||
188 | 177 | ||
189 | csum = qlcnic_temp_checksum((u32 *)ahw->fw_dump.tmpl_hdr, temp_size); | 178 | if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_TEMP_HDR)) { |
190 | if (csum) { | 179 | err = -ENOMEM; |
191 | dev_err(&adapter->pdev->dev, | 180 | goto free_mem; |
192 | "Template header checksum validation failed\n"); | ||
193 | err = -EIO; | ||
194 | goto error; | ||
195 | } | 181 | } |
196 | 182 | ||
197 | tmpl_hdr = ahw->fw_dump.tmpl_hdr; | 183 | cmd.req.arg[1] = LSD(tmp_addr_t); |
198 | tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF; | 184 | cmd.req.arg[2] = MSD(tmp_addr_t); |
199 | ahw->fw_dump.enable = 1; | 185 | cmd.req.arg[3] = 0x1000; |
200 | error: | 186 | err = qlcnic_issue_cmd(adapter, &cmd); |
201 | dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t); | 187 | |
188 | |||
189 | qlcnic_free_mbx_args(&cmd); | ||
190 | |||
191 | free_mem: | ||
192 | dma_free_coherent(&adapter->pdev->dev, 0x1000, tmp_addr, tmp_addr_t); | ||
193 | |||
202 | return err; | 194 | return err; |
203 | } | 195 | } |
204 | 196 | ||
205 | int | 197 | int |
206 | qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu) | 198 | qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu) |
207 | { | 199 | { |
200 | int err = 0; | ||
208 | struct qlcnic_cmd_args cmd; | 201 | struct qlcnic_cmd_args cmd; |
209 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; | 202 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; |
210 | 203 | ||
211 | memset(&cmd, 0, sizeof(cmd)); | 204 | if (recv_ctx->state != QLCNIC_HOST_CTX_STATE_ACTIVE) |
212 | cmd.req.cmd = QLCNIC_CDRP_CMD_SET_MTU; | 205 | return err; |
213 | cmd.req.arg1 = recv_ctx->context_id; | 206 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_MTU); |
214 | cmd.req.arg2 = mtu; | 207 | cmd.req.arg[1] = recv_ctx->context_id; |
215 | cmd.req.arg3 = 0; | 208 | cmd.req.arg[2] = mtu; |
216 | if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) { | ||
217 | qlcnic_issue_cmd(adapter, &cmd); | ||
218 | if (cmd.rsp.cmd) { | ||
219 | dev_err(&adapter->pdev->dev, "Failed to set mtu\n"); | ||
220 | return -EIO; | ||
221 | } | ||
222 | } | ||
223 | 209 | ||
224 | return 0; | 210 | err = qlcnic_issue_cmd(adapter, &cmd); |
211 | if (err) { | ||
212 | dev_err(&adapter->pdev->dev, "Failed to set mtu\n"); | ||
213 | err = -EIO; | ||
214 | } | ||
215 | qlcnic_free_mbx_args(&cmd); | ||
216 | return err; | ||
225 | } | 217 | } |
226 | 218 | ||
227 | static int | 219 | int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) |
228 | qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | ||
229 | { | 220 | { |
230 | void *addr; | 221 | void *addr; |
231 | struct qlcnic_hostrq_rx_ctx *prq; | 222 | struct qlcnic_hostrq_rx_ctx *prq; |
@@ -242,10 +233,10 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
242 | u64 phys_addr; | 233 | u64 phys_addr; |
243 | 234 | ||
244 | u8 i, nrds_rings, nsds_rings; | 235 | u8 i, nrds_rings, nsds_rings; |
236 | u16 temp_u16; | ||
245 | size_t rq_size, rsp_size; | 237 | size_t rq_size, rsp_size; |
246 | u32 cap, reg, val, reg2; | 238 | u32 cap, reg, val, reg2; |
247 | int err; | 239 | int err; |
248 | u16 temp; | ||
249 | 240 | ||
250 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; | 241 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; |
251 | 242 | ||
@@ -279,11 +270,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
279 | | QLCNIC_CAP0_VALIDOFF); | 270 | | QLCNIC_CAP0_VALIDOFF); |
280 | cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); | 271 | cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); |
281 | 272 | ||
282 | if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) | 273 | temp_u16 = offsetof(struct qlcnic_hostrq_rx_ctx, msix_handler); |
283 | cap |= QLCNIC_CAP0_LRO_MSS; | 274 | prq->valid_field_offset = cpu_to_le16(temp_u16); |
284 | |||
285 | temp = offsetof(struct qlcnic_hostrq_rx_ctx, msix_handler); | ||
286 | prq->valid_field_offset = cpu_to_le16(temp); | ||
287 | prq->txrx_sds_binding = nsds_rings - 1; | 275 | prq->txrx_sds_binding = nsds_rings - 1; |
288 | 276 | ||
289 | prq->capabilities[0] = cpu_to_le32(cap); | 277 | prq->capabilities[0] = cpu_to_le32(cap); |
@@ -329,20 +317,17 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
329 | } | 317 | } |
330 | 318 | ||
331 | phys_addr = hostrq_phys_addr; | 319 | phys_addr = hostrq_phys_addr; |
332 | memset(&cmd, 0, sizeof(cmd)); | 320 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_RX_CTX); |
333 | cmd.req.arg1 = (u32) (phys_addr >> 32); | 321 | cmd.req.arg[1] = MSD(phys_addr); |
334 | cmd.req.arg2 = (u32) (phys_addr & 0xffffffff); | 322 | cmd.req.arg[2] = LSD(phys_addr); |
335 | cmd.req.arg3 = rq_size; | 323 | cmd.req.arg[3] = rq_size; |
336 | cmd.req.cmd = QLCNIC_CDRP_CMD_CREATE_RX_CTX; | 324 | err = qlcnic_issue_cmd(adapter, &cmd); |
337 | qlcnic_issue_cmd(adapter, &cmd); | ||
338 | err = cmd.rsp.cmd; | ||
339 | if (err) { | 325 | if (err) { |
340 | dev_err(&adapter->pdev->dev, | 326 | dev_err(&adapter->pdev->dev, |
341 | "Failed to create rx ctx in firmware%d\n", err); | 327 | "Failed to create rx ctx in firmware%d\n", err); |
342 | goto out_free_rsp; | 328 | goto out_free_rsp; |
343 | } | 329 | } |
344 | 330 | ||
345 | |||
346 | prsp_rds = ((struct qlcnic_cardrsp_rds_ring *) | 331 | prsp_rds = ((struct qlcnic_cardrsp_rds_ring *) |
347 | &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); | 332 | &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); |
348 | 333 | ||
@@ -373,6 +358,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
373 | out_free_rsp: | 358 | out_free_rsp: |
374 | dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp, | 359 | dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp, |
375 | cardrsp_phys_addr); | 360 | cardrsp_phys_addr); |
361 | qlcnic_free_mbx_args(&cmd); | ||
376 | out_free_rq: | 362 | out_free_rq: |
377 | dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr); | 363 | dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr); |
378 | return err; | 364 | return err; |
@@ -381,24 +367,24 @@ out_free_rq: | |||
381 | static void | 367 | static void |
382 | qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter) | 368 | qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter) |
383 | { | 369 | { |
370 | int err; | ||
384 | struct qlcnic_cmd_args cmd; | 371 | struct qlcnic_cmd_args cmd; |
385 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; | 372 | struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; |
386 | 373 | ||
387 | memset(&cmd, 0, sizeof(cmd)); | 374 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX); |
388 | cmd.req.arg1 = recv_ctx->context_id; | 375 | cmd.req.arg[1] = recv_ctx->context_id; |
389 | cmd.req.arg2 = QLCNIC_DESTROY_CTX_RESET; | 376 | err = qlcnic_issue_cmd(adapter, &cmd); |
390 | cmd.req.arg3 = 0; | 377 | if (err) |
391 | cmd.req.cmd = QLCNIC_CDRP_CMD_DESTROY_RX_CTX; | ||
392 | qlcnic_issue_cmd(adapter, &cmd); | ||
393 | if (cmd.rsp.cmd) | ||
394 | dev_err(&adapter->pdev->dev, | 378 | dev_err(&adapter->pdev->dev, |
395 | "Failed to destroy rx ctx in firmware\n"); | 379 | "Failed to destroy rx ctx in firmware\n"); |
396 | 380 | ||
397 | recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED; | 381 | recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED; |
382 | qlcnic_free_mbx_args(&cmd); | ||
398 | } | 383 | } |
399 | 384 | ||
400 | static int | 385 | int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter, |
401 | qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | 386 | struct qlcnic_host_tx_ring *tx_ring, |
387 | int ring) | ||
402 | { | 388 | { |
403 | struct qlcnic_hostrq_tx_ctx *prq; | 389 | struct qlcnic_hostrq_tx_ctx *prq; |
404 | struct qlcnic_hostrq_cds_ring *prq_cds; | 390 | struct qlcnic_hostrq_cds_ring *prq_cds; |
@@ -410,7 +396,6 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | |||
410 | int err; | 396 | int err; |
411 | u64 phys_addr; | 397 | u64 phys_addr; |
412 | dma_addr_t rq_phys_addr, rsp_phys_addr; | 398 | dma_addr_t rq_phys_addr, rsp_phys_addr; |
413 | struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; | ||
414 | 399 | ||
415 | /* reset host resources */ | 400 | /* reset host resources */ |
416 | tx_ring->producer = 0; | 401 | tx_ring->producer = 0; |
@@ -445,9 +430,9 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | |||
445 | 430 | ||
446 | prq->host_int_crb_mode = | 431 | prq->host_int_crb_mode = |
447 | cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED); | 432 | cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED); |
433 | prq->msi_index = 0; | ||
448 | 434 | ||
449 | prq->interrupt_ctl = 0; | 435 | prq->interrupt_ctl = 0; |
450 | prq->msi_index = 0; | ||
451 | prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr); | 436 | prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr); |
452 | 437 | ||
453 | prq_cds = &prq->cds_ring; | 438 | prq_cds = &prq->cds_ring; |
@@ -456,19 +441,17 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | |||
456 | prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); | 441 | prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); |
457 | 442 | ||
458 | phys_addr = rq_phys_addr; | 443 | phys_addr = rq_phys_addr; |
459 | memset(&cmd, 0, sizeof(cmd)); | 444 | |
460 | cmd.req.arg1 = (u32)(phys_addr >> 32); | 445 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX); |
461 | cmd.req.arg2 = ((u32)phys_addr & 0xffffffff); | 446 | cmd.req.arg[1] = MSD(phys_addr); |
462 | cmd.req.arg3 = rq_size; | 447 | cmd.req.arg[2] = LSD(phys_addr); |
463 | cmd.req.cmd = QLCNIC_CDRP_CMD_CREATE_TX_CTX; | 448 | cmd.req.arg[3] = rq_size; |
464 | qlcnic_issue_cmd(adapter, &cmd); | 449 | err = qlcnic_issue_cmd(adapter, &cmd); |
465 | err = cmd.rsp.cmd; | ||
466 | 450 | ||
467 | if (err == QLCNIC_RCODE_SUCCESS) { | 451 | if (err == QLCNIC_RCODE_SUCCESS) { |
468 | temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); | 452 | temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); |
469 | tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp; | 453 | tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp; |
470 | 454 | tx_ring->ctx_id = le16_to_cpu(prsp->context_id); | |
471 | adapter->tx_ring->ctx_id = le16_to_cpu(prsp->context_id); | ||
472 | } else { | 455 | } else { |
473 | dev_err(&adapter->pdev->dev, | 456 | dev_err(&adapter->pdev->dev, |
474 | "Failed to create tx ctx in firmware%d\n", err); | 457 | "Failed to create tx ctx in firmware%d\n", err); |
@@ -476,41 +459,40 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | |||
476 | } | 459 | } |
477 | 460 | ||
478 | dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr, | 461 | dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr, |
479 | rsp_phys_addr); | 462 | rsp_phys_addr); |
480 | 463 | ||
481 | out_free_rq: | 464 | out_free_rq: |
482 | dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr); | 465 | dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr); |
466 | qlcnic_free_mbx_args(&cmd); | ||
483 | 467 | ||
484 | return err; | 468 | return err; |
485 | } | 469 | } |
486 | 470 | ||
487 | static void | 471 | static void |
488 | qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter) | 472 | qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter, |
473 | struct qlcnic_host_tx_ring *tx_ring) | ||
489 | { | 474 | { |
490 | struct qlcnic_cmd_args cmd; | 475 | struct qlcnic_cmd_args cmd; |
491 | 476 | ||
492 | memset(&cmd, 0, sizeof(cmd)); | 477 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX); |
493 | cmd.req.arg1 = adapter->tx_ring->ctx_id; | 478 | cmd.req.arg[1] = tx_ring->ctx_id; |
494 | cmd.req.arg2 = QLCNIC_DESTROY_CTX_RESET; | 479 | if (qlcnic_issue_cmd(adapter, &cmd)) |
495 | cmd.req.arg3 = 0; | ||
496 | cmd.req.cmd = QLCNIC_CDRP_CMD_DESTROY_TX_CTX; | ||
497 | qlcnic_issue_cmd(adapter, &cmd); | ||
498 | if (cmd.rsp.cmd) | ||
499 | dev_err(&adapter->pdev->dev, | 480 | dev_err(&adapter->pdev->dev, |
500 | "Failed to destroy tx ctx in firmware\n"); | 481 | "Failed to destroy tx ctx in firmware\n"); |
482 | qlcnic_free_mbx_args(&cmd); | ||
501 | } | 483 | } |
502 | 484 | ||
503 | int | 485 | int |
504 | qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config) | 486 | qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config) |
505 | { | 487 | { |
488 | int err; | ||
506 | struct qlcnic_cmd_args cmd; | 489 | struct qlcnic_cmd_args cmd; |
507 | 490 | ||
508 | memset(&cmd, 0, sizeof(cmd)); | 491 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_PORT); |
509 | cmd.req.arg1 = config; | 492 | cmd.req.arg[1] = config; |
510 | cmd.req.cmd = QLCNIC_CDRP_CMD_CONFIG_PORT; | 493 | err = qlcnic_issue_cmd(adapter, &cmd); |
511 | qlcnic_issue_cmd(adapter, &cmd); | 494 | qlcnic_free_mbx_args(&cmd); |
512 | 495 | return err; | |
513 | return cmd.rsp.cmd; | ||
514 | } | 496 | } |
515 | 497 | ||
516 | int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) | 498 | int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) |
@@ -584,36 +566,49 @@ err_out_free: | |||
584 | return err; | 566 | return err; |
585 | } | 567 | } |
586 | 568 | ||
587 | 569 | int qlcnic_fw_create_ctx(struct qlcnic_adapter *dev) | |
588 | int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter) | ||
589 | { | 570 | { |
590 | int err; | 571 | int i, err, ring; |
591 | 572 | ||
592 | if (adapter->flags & QLCNIC_NEED_FLR) { | 573 | if (dev->flags & QLCNIC_NEED_FLR) { |
593 | pci_reset_function(adapter->pdev); | 574 | pci_reset_function(dev->pdev); |
594 | adapter->flags &= ~QLCNIC_NEED_FLR; | 575 | dev->flags &= ~QLCNIC_NEED_FLR; |
595 | } | 576 | } |
596 | 577 | ||
597 | err = qlcnic_fw_cmd_create_rx_ctx(adapter); | 578 | err = qlcnic_fw_cmd_create_rx_ctx(dev); |
598 | if (err) | 579 | if (err) |
599 | return err; | 580 | return err; |
600 | 581 | ||
601 | err = qlcnic_fw_cmd_create_tx_ctx(adapter); | 582 | for (ring = 0; ring < dev->max_drv_tx_rings; ring++) { |
602 | if (err) { | 583 | err = qlcnic_fw_cmd_create_tx_ctx(dev, |
603 | qlcnic_fw_cmd_destroy_rx_ctx(adapter); | 584 | &dev->tx_ring[ring], |
604 | return err; | 585 | ring); |
586 | if (err) { | ||
587 | qlcnic_fw_cmd_destroy_rx_ctx(dev); | ||
588 | if (ring == 0) | ||
589 | return err; | ||
590 | |||
591 | for (i = 0; i < ring; i++) | ||
592 | qlcnic_fw_cmd_destroy_tx_ctx(dev, | ||
593 | &dev->tx_ring[i]); | ||
594 | |||
595 | return err; | ||
596 | } | ||
605 | } | 597 | } |
606 | 598 | ||
607 | set_bit(__QLCNIC_FW_ATTACHED, &adapter->state); | 599 | set_bit(__QLCNIC_FW_ATTACHED, &dev->state); |
608 | return 0; | 600 | return 0; |
609 | } | 601 | } |
610 | 602 | ||
611 | void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter) | 603 | void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter) |
612 | { | 604 | { |
605 | int ring; | ||
606 | |||
613 | if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) { | 607 | if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) { |
614 | qlcnic_fw_cmd_destroy_rx_ctx(adapter); | 608 | qlcnic_fw_cmd_destroy_rx_ctx(adapter); |
615 | qlcnic_fw_cmd_destroy_tx_ctx(adapter); | 609 | for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) |
616 | 610 | qlcnic_fw_cmd_destroy_tx_ctx(adapter, | |
611 | &adapter->tx_ring[ring]); | ||
617 | /* Allow dma queues to drain after context reset */ | 612 | /* Allow dma queues to drain after context reset */ |
618 | mdelay(20); | 613 | mdelay(20); |
619 | } | 614 | } |
@@ -671,40 +666,43 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) | |||
671 | } | 666 | } |
672 | 667 | ||
673 | 668 | ||
674 | /* Get MAC address of a NIC partition */ | 669 | int qlcnic_82xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) |
675 | int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) | ||
676 | { | 670 | { |
677 | int err; | 671 | int err, i; |
678 | struct qlcnic_cmd_args cmd; | 672 | struct qlcnic_cmd_args cmd; |
673 | u32 mac_low, mac_high; | ||
679 | 674 | ||
680 | memset(&cmd, 0, sizeof(cmd)); | 675 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS); |
681 | cmd.req.arg1 = adapter->ahw->pci_func | BIT_8; | 676 | cmd.req.arg[1] = adapter->ahw->pci_func | BIT_8; |
682 | cmd.req.cmd = QLCNIC_CDRP_CMD_MAC_ADDRESS; | 677 | err = qlcnic_issue_cmd(adapter, &cmd); |
683 | cmd.rsp.arg1 = cmd.rsp.arg2 = 1; | ||
684 | qlcnic_issue_cmd(adapter, &cmd); | ||
685 | err = cmd.rsp.cmd; | ||
686 | 678 | ||
687 | if (err == QLCNIC_RCODE_SUCCESS) | 679 | if (err == QLCNIC_RCODE_SUCCESS) { |
688 | qlcnic_fetch_mac(cmd.rsp.arg1, cmd.rsp.arg2, 0, mac); | 680 | mac_low = cmd.rsp.arg[1]; |
689 | else { | 681 | mac_high = cmd.rsp.arg[2]; |
682 | |||
683 | for (i = 0; i < 2; i++) | ||
684 | mac[i] = (u8) (mac_high >> ((1 - i) * 8)); | ||
685 | for (i = 2; i < 6; i++) | ||
686 | mac[i] = (u8) (mac_low >> ((5 - i) * 8)); | ||
687 | } else { | ||
690 | dev_err(&adapter->pdev->dev, | 688 | dev_err(&adapter->pdev->dev, |
691 | "Failed to get mac address%d\n", err); | 689 | "Failed to get mac address%d\n", err); |
692 | err = -EIO; | 690 | err = -EIO; |
693 | } | 691 | } |
694 | 692 | qlcnic_free_mbx_args(&cmd); | |
695 | return err; | 693 | return err; |
696 | } | 694 | } |
697 | 695 | ||
698 | /* Get info of a NIC partition */ | 696 | /* Get info of a NIC partition */ |
699 | int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, | 697 | int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter, |
700 | struct qlcnic_info *npar_info, u8 func_id) | 698 | struct qlcnic_info *npar_info, u8 func_id) |
701 | { | 699 | { |
702 | int err; | 700 | int err; |
703 | dma_addr_t nic_dma_t; | 701 | dma_addr_t nic_dma_t; |
704 | struct qlcnic_info_le *nic_info; | 702 | const struct qlcnic_info_le *nic_info; |
705 | void *nic_info_addr; | 703 | void *nic_info_addr; |
706 | struct qlcnic_cmd_args cmd; | 704 | struct qlcnic_cmd_args cmd; |
707 | size_t nic_size = sizeof(struct qlcnic_info_le); | 705 | size_t nic_size = sizeof(struct qlcnic_info_le); |
708 | 706 | ||
709 | nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, | 707 | nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size, |
710 | &nic_dma_t, GFP_KERNEL); | 708 | &nic_dma_t, GFP_KERNEL); |
@@ -713,47 +711,39 @@ int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, | |||
713 | memset(nic_info_addr, 0, nic_size); | 711 | memset(nic_info_addr, 0, nic_size); |
714 | 712 | ||
715 | nic_info = nic_info_addr; | 713 | nic_info = nic_info_addr; |
716 | memset(&cmd, 0, sizeof(cmd)); | ||
717 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_NIC_INFO; | ||
718 | cmd.req.arg1 = MSD(nic_dma_t); | ||
719 | cmd.req.arg2 = LSD(nic_dma_t); | ||
720 | cmd.req.arg3 = (func_id << 16 | nic_size); | ||
721 | qlcnic_issue_cmd(adapter, &cmd); | ||
722 | err = cmd.rsp.cmd; | ||
723 | 714 | ||
724 | if (err == QLCNIC_RCODE_SUCCESS) { | 715 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO); |
716 | cmd.req.arg[1] = MSD(nic_dma_t); | ||
717 | cmd.req.arg[2] = LSD(nic_dma_t); | ||
718 | cmd.req.arg[3] = (func_id << 16 | nic_size); | ||
719 | err = qlcnic_issue_cmd(adapter, &cmd); | ||
720 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
721 | dev_err(&adapter->pdev->dev, | ||
722 | "Failed to get nic info%d\n", err); | ||
723 | err = -EIO; | ||
724 | } else { | ||
725 | npar_info->pci_func = le16_to_cpu(nic_info->pci_func); | 725 | npar_info->pci_func = le16_to_cpu(nic_info->pci_func); |
726 | npar_info->op_mode = le16_to_cpu(nic_info->op_mode); | 726 | npar_info->op_mode = le16_to_cpu(nic_info->op_mode); |
727 | npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw); | ||
728 | npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw); | ||
727 | npar_info->phys_port = le16_to_cpu(nic_info->phys_port); | 729 | npar_info->phys_port = le16_to_cpu(nic_info->phys_port); |
728 | npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode); | 730 | npar_info->switch_mode = le16_to_cpu(nic_info->switch_mode); |
729 | npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques); | 731 | npar_info->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques); |
730 | npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); | 732 | npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); |
731 | npar_info->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw); | ||
732 | npar_info->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw); | ||
733 | npar_info->capabilities = le32_to_cpu(nic_info->capabilities); | 733 | npar_info->capabilities = le32_to_cpu(nic_info->capabilities); |
734 | npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); | 734 | npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); |
735 | |||
736 | dev_info(&adapter->pdev->dev, | ||
737 | "phy port: %d switch_mode: %d,\n" | ||
738 | "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n" | ||
739 | "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n", | ||
740 | npar_info->phys_port, npar_info->switch_mode, | ||
741 | npar_info->max_tx_ques, npar_info->max_rx_ques, | ||
742 | npar_info->min_tx_bw, npar_info->max_tx_bw, | ||
743 | npar_info->max_mtu, npar_info->capabilities); | ||
744 | } else { | ||
745 | dev_err(&adapter->pdev->dev, | ||
746 | "Failed to get nic info%d\n", err); | ||
747 | err = -EIO; | ||
748 | } | 735 | } |
749 | 736 | ||
750 | dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr, | 737 | dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr, |
751 | nic_dma_t); | 738 | nic_dma_t); |
739 | qlcnic_free_mbx_args(&cmd); | ||
740 | |||
752 | return err; | 741 | return err; |
753 | } | 742 | } |
754 | 743 | ||
755 | /* Configure a NIC partition */ | 744 | /* Configure a NIC partition */ |
756 | int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | 745 | int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *adapter, |
746 | struct qlcnic_info *nic) | ||
757 | { | 747 | { |
758 | int err = -EIO; | 748 | int err = -EIO; |
759 | dma_addr_t nic_dma_t; | 749 | dma_addr_t nic_dma_t; |
@@ -784,13 +774,11 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | |||
784 | nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw); | 774 | nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw); |
785 | nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw); | 775 | nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw); |
786 | 776 | ||
787 | memset(&cmd, 0, sizeof(cmd)); | 777 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO); |
788 | cmd.req.cmd = QLCNIC_CDRP_CMD_SET_NIC_INFO; | 778 | cmd.req.arg[1] = MSD(nic_dma_t); |
789 | cmd.req.arg1 = MSD(nic_dma_t); | 779 | cmd.req.arg[2] = LSD(nic_dma_t); |
790 | cmd.req.arg2 = LSD(nic_dma_t); | 780 | cmd.req.arg[3] = ((nic->pci_func << 16) | nic_size); |
791 | cmd.req.arg3 = ((nic->pci_func << 16) | nic_size); | 781 | err = qlcnic_issue_cmd(adapter, &cmd); |
792 | qlcnic_issue_cmd(adapter, &cmd); | ||
793 | err = cmd.rsp.cmd; | ||
794 | 782 | ||
795 | if (err != QLCNIC_RCODE_SUCCESS) { | 783 | if (err != QLCNIC_RCODE_SUCCESS) { |
796 | dev_err(&adapter->pdev->dev, | 784 | dev_err(&adapter->pdev->dev, |
@@ -800,12 +788,14 @@ int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | |||
800 | 788 | ||
801 | dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr, | 789 | dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr, |
802 | nic_dma_t); | 790 | nic_dma_t); |
791 | qlcnic_free_mbx_args(&cmd); | ||
792 | |||
803 | return err; | 793 | return err; |
804 | } | 794 | } |
805 | 795 | ||
806 | /* Get PCI Info of a partition */ | 796 | /* Get PCI Info of a partition */ |
807 | int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, | 797 | int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *adapter, |
808 | struct qlcnic_pci_info *pci_info) | 798 | struct qlcnic_pci_info *pci_info) |
809 | { | 799 | { |
810 | int err = 0, i; | 800 | int err = 0, i; |
811 | struct qlcnic_cmd_args cmd; | 801 | struct qlcnic_cmd_args cmd; |
@@ -822,13 +812,11 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, | |||
822 | memset(pci_info_addr, 0, pci_size); | 812 | memset(pci_info_addr, 0, pci_size); |
823 | 813 | ||
824 | npar = pci_info_addr; | 814 | npar = pci_info_addr; |
825 | memset(&cmd, 0, sizeof(cmd)); | 815 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO); |
826 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_PCI_INFO; | 816 | cmd.req.arg[1] = MSD(pci_info_dma_t); |
827 | cmd.req.arg1 = MSD(pci_info_dma_t); | 817 | cmd.req.arg[2] = LSD(pci_info_dma_t); |
828 | cmd.req.arg2 = LSD(pci_info_dma_t); | 818 | cmd.req.arg[3] = pci_size; |
829 | cmd.req.arg3 = pci_size; | 819 | err = qlcnic_issue_cmd(adapter, &cmd); |
830 | qlcnic_issue_cmd(adapter, &cmd); | ||
831 | err = cmd.rsp.cmd; | ||
832 | 820 | ||
833 | adapter->ahw->act_pci_func = 0; | 821 | adapter->ahw->act_pci_func = 0; |
834 | if (err == QLCNIC_RCODE_SUCCESS) { | 822 | if (err == QLCNIC_RCODE_SUCCESS) { |
@@ -854,6 +842,8 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, | |||
854 | 842 | ||
855 | dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr, | 843 | dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr, |
856 | pci_info_dma_t); | 844 | pci_info_dma_t); |
845 | qlcnic_free_mbx_args(&cmd); | ||
846 | |||
857 | return err; | 847 | return err; |
858 | } | 848 | } |
859 | 849 | ||
@@ -872,21 +862,19 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, | |||
872 | arg1 = id | (enable_mirroring ? BIT_4 : 0); | 862 | arg1 = id | (enable_mirroring ? BIT_4 : 0); |
873 | arg1 |= pci_func << 8; | 863 | arg1 |= pci_func << 8; |
874 | 864 | ||
875 | memset(&cmd, 0, sizeof(cmd)); | 865 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORTMIRRORING); |
876 | cmd.req.cmd = QLCNIC_CDRP_CMD_SET_PORTMIRRORING; | 866 | cmd.req.arg[1] = arg1; |
877 | cmd.req.arg1 = arg1; | 867 | err = qlcnic_issue_cmd(adapter, &cmd); |
878 | qlcnic_issue_cmd(adapter, &cmd); | ||
879 | err = cmd.rsp.cmd; | ||
880 | 868 | ||
881 | if (err != QLCNIC_RCODE_SUCCESS) { | 869 | if (err != QLCNIC_RCODE_SUCCESS) |
882 | dev_err(&adapter->pdev->dev, | 870 | dev_err(&adapter->pdev->dev, |
883 | "Failed to configure port mirroring%d on eswitch:%d\n", | 871 | "Failed to configure port mirroring%d on eswitch:%d\n", |
884 | pci_func, id); | 872 | pci_func, id); |
885 | } else { | 873 | else |
886 | dev_info(&adapter->pdev->dev, | 874 | dev_info(&adapter->pdev->dev, |
887 | "Configured eSwitch %d for port mirroring:%d\n", | 875 | "Configured eSwitch %d for port mirroring:%d\n", |
888 | id, pci_func); | 876 | id, pci_func); |
889 | } | 877 | qlcnic_free_mbx_args(&cmd); |
890 | 878 | ||
891 | return err; | 879 | return err; |
892 | } | 880 | } |
@@ -923,13 +911,11 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, | |||
923 | arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12; | 911 | arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12; |
924 | arg1 |= rx_tx << 15 | stats_size << 16; | 912 | arg1 |= rx_tx << 15 | stats_size << 16; |
925 | 913 | ||
926 | memset(&cmd, 0, sizeof(cmd)); | 914 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_ESWITCH_STATS); |
927 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_ESWITCH_STATS; | 915 | cmd.req.arg[1] = arg1; |
928 | cmd.req.arg1 = arg1; | 916 | cmd.req.arg[2] = MSD(stats_dma_t); |
929 | cmd.req.arg2 = MSD(stats_dma_t); | 917 | cmd.req.arg[3] = LSD(stats_dma_t); |
930 | cmd.req.arg3 = LSD(stats_dma_t); | 918 | err = qlcnic_issue_cmd(adapter, &cmd); |
931 | qlcnic_issue_cmd(adapter, &cmd); | ||
932 | err = cmd.rsp.cmd; | ||
933 | 919 | ||
934 | if (!err) { | 920 | if (!err) { |
935 | stats = stats_addr; | 921 | stats = stats_addr; |
@@ -949,6 +935,8 @@ int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, | |||
949 | 935 | ||
950 | dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, | 936 | dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, |
951 | stats_dma_t); | 937 | stats_dma_t); |
938 | qlcnic_free_mbx_args(&cmd); | ||
939 | |||
952 | return err; | 940 | return err; |
953 | } | 941 | } |
954 | 942 | ||
@@ -963,6 +951,9 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, | |||
963 | void *stats_addr; | 951 | void *stats_addr; |
964 | int err; | 952 | int err; |
965 | 953 | ||
954 | if (mac_stats == NULL) | ||
955 | return -ENOMEM; | ||
956 | |||
966 | stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, | 957 | stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size, |
967 | &stats_dma_t, GFP_KERNEL); | 958 | &stats_dma_t, GFP_KERNEL); |
968 | if (!stats_addr) { | 959 | if (!stats_addr) { |
@@ -971,15 +962,11 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, | |||
971 | return -ENOMEM; | 962 | return -ENOMEM; |
972 | } | 963 | } |
973 | memset(stats_addr, 0, stats_size); | 964 | memset(stats_addr, 0, stats_size); |
974 | memset(&cmd, 0, sizeof(cmd)); | 965 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_MAC_STATS); |
975 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_MAC_STATS; | 966 | cmd.req.arg[1] = stats_size << 16; |
976 | cmd.req.arg1 = stats_size << 16; | 967 | cmd.req.arg[2] = MSD(stats_dma_t); |
977 | cmd.req.arg2 = MSD(stats_dma_t); | 968 | cmd.req.arg[3] = LSD(stats_dma_t); |
978 | cmd.req.arg3 = LSD(stats_dma_t); | 969 | err = qlcnic_issue_cmd(adapter, &cmd); |
979 | |||
980 | qlcnic_issue_cmd(adapter, &cmd); | ||
981 | err = cmd.rsp.cmd; | ||
982 | |||
983 | if (!err) { | 970 | if (!err) { |
984 | stats = stats_addr; | 971 | stats = stats_addr; |
985 | mac_stats->mac_tx_frames = le64_to_cpu(stats->mac_tx_frames); | 972 | mac_stats->mac_tx_frames = le64_to_cpu(stats->mac_tx_frames); |
@@ -1001,10 +988,16 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, | |||
1001 | mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber); | 988 | mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber); |
1002 | mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped); | 989 | mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped); |
1003 | mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error); | 990 | mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error); |
991 | } else { | ||
992 | dev_err(&adapter->pdev->dev, | ||
993 | "%s: Get mac stats failed, err=%d.\n", __func__, err); | ||
1004 | } | 994 | } |
1005 | 995 | ||
1006 | dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, | 996 | dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, |
1007 | stats_dma_t); | 997 | stats_dma_t); |
998 | |||
999 | qlcnic_free_mbx_args(&cmd); | ||
1000 | |||
1008 | return err; | 1001 | return err; |
1009 | } | 1002 | } |
1010 | 1003 | ||
@@ -1065,7 +1058,7 @@ int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, | |||
1065 | int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, | 1058 | int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, |
1066 | const u8 port, const u8 rx_tx) | 1059 | const u8 port, const u8 rx_tx) |
1067 | { | 1060 | { |
1068 | 1061 | int err; | |
1069 | u32 arg1; | 1062 | u32 arg1; |
1070 | struct qlcnic_cmd_args cmd; | 1063 | struct qlcnic_cmd_args cmd; |
1071 | 1064 | ||
@@ -1088,15 +1081,16 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, | |||
1088 | arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12; | 1081 | arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12; |
1089 | arg1 |= BIT_14 | rx_tx << 15; | 1082 | arg1 |= BIT_14 | rx_tx << 15; |
1090 | 1083 | ||
1091 | memset(&cmd, 0, sizeof(cmd)); | 1084 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_ESWITCH_STATS); |
1092 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_ESWITCH_STATS; | 1085 | cmd.req.arg[1] = arg1; |
1093 | cmd.req.arg1 = arg1; | 1086 | err = qlcnic_issue_cmd(adapter, &cmd); |
1094 | qlcnic_issue_cmd(adapter, &cmd); | 1087 | qlcnic_free_mbx_args(&cmd); |
1095 | return cmd.rsp.cmd; | 1088 | return err; |
1096 | 1089 | ||
1097 | err_ret: | 1090 | err_ret: |
1098 | dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d" | 1091 | dev_err(&adapter->pdev->dev, |
1099 | "rx_ctx=%d\n", func_esw, port, rx_tx); | 1092 | "Invalid args func_esw %d port %d rx_ctx %d\n", |
1093 | func_esw, port, rx_tx); | ||
1100 | return -EIO; | 1094 | return -EIO; |
1101 | } | 1095 | } |
1102 | 1096 | ||
@@ -1109,22 +1103,21 @@ __qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, | |||
1109 | u8 pci_func; | 1103 | u8 pci_func; |
1110 | pci_func = (*arg1 >> 8); | 1104 | pci_func = (*arg1 >> 8); |
1111 | 1105 | ||
1112 | cmd.req.cmd = QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG; | 1106 | qlcnic_alloc_mbx_args(&cmd, adapter, |
1113 | cmd.req.arg1 = *arg1; | 1107 | QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG); |
1114 | cmd.rsp.arg1 = cmd.rsp.arg2 = 1; | 1108 | cmd.req.arg[1] = *arg1; |
1115 | qlcnic_issue_cmd(adapter, &cmd); | 1109 | err = qlcnic_issue_cmd(adapter, &cmd); |
1116 | *arg1 = cmd.rsp.arg1; | 1110 | *arg1 = cmd.rsp.arg[1]; |
1117 | *arg2 = cmd.rsp.arg2; | 1111 | *arg2 = cmd.rsp.arg[2]; |
1118 | err = cmd.rsp.cmd; | 1112 | qlcnic_free_mbx_args(&cmd); |
1119 | 1113 | ||
1120 | if (err == QLCNIC_RCODE_SUCCESS) { | 1114 | if (err == QLCNIC_RCODE_SUCCESS) |
1121 | dev_info(&adapter->pdev->dev, | 1115 | dev_info(&adapter->pdev->dev, |
1122 | "eSwitch port config for pci func %d\n", pci_func); | 1116 | "eSwitch port config for pci func %d\n", pci_func); |
1123 | } else { | 1117 | else |
1124 | dev_err(&adapter->pdev->dev, | 1118 | dev_err(&adapter->pdev->dev, |
1125 | "Failed to get eswitch port config for pci func %d\n", | 1119 | "Failed to get eswitch port config for pci func %d\n", |
1126 | pci_func); | 1120 | pci_func); |
1127 | } | ||
1128 | return err; | 1121 | return err; |
1129 | } | 1122 | } |
1130 | /* Configure eSwitch port | 1123 | /* Configure eSwitch port |
@@ -1189,20 +1182,18 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, | |||
1189 | return err; | 1182 | return err; |
1190 | } | 1183 | } |
1191 | 1184 | ||
1192 | memset(&cmd, 0, sizeof(cmd)); | 1185 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_ESWITCH); |
1193 | cmd.req.cmd = QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH; | 1186 | cmd.req.arg[1] = arg1; |
1194 | cmd.req.arg1 = arg1; | 1187 | cmd.req.arg[2] = arg2; |
1195 | cmd.req.arg2 = arg2; | 1188 | err = qlcnic_issue_cmd(adapter, &cmd); |
1196 | qlcnic_issue_cmd(adapter, &cmd); | 1189 | qlcnic_free_mbx_args(&cmd); |
1197 | 1190 | ||
1198 | err = cmd.rsp.cmd; | 1191 | if (err != QLCNIC_RCODE_SUCCESS) |
1199 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
1200 | dev_err(&adapter->pdev->dev, | 1192 | dev_err(&adapter->pdev->dev, |
1201 | "Failed to configure eswitch pci func %d\n", pci_func); | 1193 | "Failed to configure eswitch pci func %d\n", pci_func); |
1202 | } else { | 1194 | else |
1203 | dev_info(&adapter->pdev->dev, | 1195 | dev_info(&adapter->pdev->dev, |
1204 | "Configured eSwitch for pci func %d\n", pci_func); | 1196 | "Configured eSwitch for pci func %d\n", pci_func); |
1205 | } | ||
1206 | 1197 | ||
1207 | return err; | 1198 | return err; |
1208 | } | 1199 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 74b98110c5b4..064f36b66b3e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -705,20 +705,19 @@ static int qlcnic_irq_test(struct net_device *netdev) | |||
705 | goto clear_it; | 705 | goto clear_it; |
706 | 706 | ||
707 | adapter->ahw->diag_cnt = 0; | 707 | adapter->ahw->diag_cnt = 0; |
708 | memset(&cmd, 0, sizeof(cmd)); | 708 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST); |
709 | cmd.req.cmd = QLCNIC_CDRP_CMD_INTRPT_TEST; | 709 | |
710 | cmd.req.arg1 = adapter->ahw->pci_func; | 710 | cmd.req.arg[1] = adapter->ahw->pci_func; |
711 | qlcnic_issue_cmd(adapter, &cmd); | 711 | ret = qlcnic_issue_cmd(adapter, &cmd); |
712 | ret = cmd.rsp.cmd; | ||
713 | 712 | ||
714 | if (ret) | 713 | if (ret) |
715 | goto done; | 714 | goto done; |
716 | 715 | ||
717 | msleep(10); | 716 | usleep_range(1000, 12000); |
718 | |||
719 | ret = !adapter->ahw->diag_cnt; | 717 | ret = !adapter->ahw->diag_cnt; |
720 | 718 | ||
721 | done: | 719 | done: |
720 | qlcnic_free_mbx_args(&cmd); | ||
722 | qlcnic_diag_free_res(netdev, max_sds_rings); | 721 | qlcnic_diag_free_res(netdev, max_sds_rings); |
723 | 722 | ||
724 | clear_it: | 723 | clear_it: |
@@ -845,7 +844,7 @@ static int qlcnic_loopback_test(struct net_device *netdev, u8 mode) | |||
845 | 844 | ||
846 | ret = qlcnic_do_lb_test(adapter, mode); | 845 | ret = qlcnic_do_lb_test(adapter, mode); |
847 | 846 | ||
848 | qlcnic_clear_lb_mode(adapter); | 847 | qlcnic_clear_lb_mode(adapter, mode); |
849 | 848 | ||
850 | free_res: | 849 | free_res: |
851 | qlcnic_diag_free_res(netdev, max_sds_rings); | 850 | qlcnic_diag_free_res(netdev, max_sds_rings); |
@@ -1307,7 +1306,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) | |||
1307 | return 0; | 1306 | return 0; |
1308 | } | 1307 | } |
1309 | netdev_info(netdev, "Forcing a FW dump\n"); | 1308 | netdev_info(netdev, "Forcing a FW dump\n"); |
1310 | qlcnic_dev_request_reset(adapter); | 1309 | qlcnic_dev_request_reset(adapter, 0); |
1311 | break; | 1310 | break; |
1312 | case QLCNIC_DISABLE_FW_DUMP: | 1311 | case QLCNIC_DISABLE_FW_DUMP: |
1313 | if (fw_dump->enable && fw_dump->tmpl_hdr) { | 1312 | if (fw_dump->enable && fw_dump->tmpl_hdr) { |
@@ -1327,7 +1326,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val) | |||
1327 | return 0; | 1326 | return 0; |
1328 | case QLCNIC_FORCE_FW_RESET: | 1327 | case QLCNIC_FORCE_FW_RESET: |
1329 | netdev_info(netdev, "Forcing a FW reset\n"); | 1328 | netdev_info(netdev, "Forcing a FW reset\n"); |
1330 | qlcnic_dev_request_reset(adapter); | 1329 | qlcnic_dev_request_reset(adapter, 0); |
1331 | adapter->flags &= ~QLCNIC_FW_RESET_OWNER; | 1330 | adapter->flags &= ~QLCNIC_FW_RESET_OWNER; |
1332 | return 0; | 1331 | return 0; |
1333 | case QLCNIC_SET_QUIESCENT: | 1332 | case QLCNIC_SET_QUIESCENT: |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index 49cc1ac4f057..fa2b8c63eedb 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | 13 | ||
14 | #include "qlcnic_hw.h" | ||
15 | |||
14 | /* | 16 | /* |
15 | * The basic unit of access when reading/writing control registers. | 17 | * The basic unit of access when reading/writing control registers. |
16 | */ | 18 | */ |
@@ -568,6 +570,9 @@ enum { | |||
568 | #define QLCNIC_REG(X) (NIC_CRB_BASE+(X)) | 570 | #define QLCNIC_REG(X) (NIC_CRB_BASE+(X)) |
569 | #define QLCNIC_REG_2(X) (NIC_CRB_BASE_2+(X)) | 571 | #define QLCNIC_REG_2(X) (NIC_CRB_BASE_2+(X)) |
570 | 572 | ||
573 | #define QLCNIC_CDRP_MAX_ARGS 4 | ||
574 | #define QLCNIC_CDRP_ARG(i) (QLCNIC_REG(0x18 + ((i) * 4))) | ||
575 | |||
571 | #define QLCNIC_CDRP_CRB_OFFSET (QLCNIC_REG(0x18)) | 576 | #define QLCNIC_CDRP_CRB_OFFSET (QLCNIC_REG(0x18)) |
572 | #define QLCNIC_ARG1_CRB_OFFSET (QLCNIC_REG(0x1c)) | 577 | #define QLCNIC_ARG1_CRB_OFFSET (QLCNIC_REG(0x1c)) |
573 | #define QLCNIC_ARG2_CRB_OFFSET (QLCNIC_REG(0x20)) | 578 | #define QLCNIC_ARG2_CRB_OFFSET (QLCNIC_REG(0x20)) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 7a6d5ebe4e0f..284618be3402 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -417,9 +417,8 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | static int | 420 | int qlcnic_82xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, |
421 | qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, | 421 | __le16 vlan_id, u8 op) |
422 | __le16 vlan_id, unsigned op) | ||
423 | { | 422 | { |
424 | struct qlcnic_nic_req req; | 423 | struct qlcnic_nic_req req; |
425 | struct qlcnic_mac_req *mac_req; | 424 | struct qlcnic_mac_req *mac_req; |
@@ -516,7 +515,7 @@ send_fw_cmd: | |||
516 | qlcnic_nic_set_promisc(adapter, mode); | 515 | qlcnic_nic_set_promisc(adapter, mode); |
517 | } | 516 | } |
518 | 517 | ||
519 | int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) | 518 | int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) |
520 | { | 519 | { |
521 | struct qlcnic_nic_req req; | 520 | struct qlcnic_nic_req req; |
522 | u64 word; | 521 | u64 word; |
@@ -620,12 +619,13 @@ static int qlcnic_set_fw_loopback(struct qlcnic_adapter *adapter, u8 flag) | |||
620 | return rv; | 619 | return rv; |
621 | } | 620 | } |
622 | 621 | ||
623 | int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) | 622 | int qlcnic_82xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) |
624 | { | 623 | { |
625 | if (qlcnic_set_fw_loopback(adapter, mode)) | 624 | if (qlcnic_set_fw_loopback(adapter, mode)) |
626 | return -EIO; | 625 | return -EIO; |
627 | 626 | ||
628 | if (qlcnic_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL)) { | 627 | if (qlcnic_nic_set_promisc(adapter, |
628 | VPORT_MISS_MODE_ACCEPT_ALL)) { | ||
629 | qlcnic_set_fw_loopback(adapter, 0); | 629 | qlcnic_set_fw_loopback(adapter, 0); |
630 | return -EIO; | 630 | return -EIO; |
631 | } | 631 | } |
@@ -634,11 +634,11 @@ int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode) | |||
634 | return 0; | 634 | return 0; |
635 | } | 635 | } |
636 | 636 | ||
637 | void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter) | 637 | int qlcnic_82xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode) |
638 | { | 638 | { |
639 | int mode = VPORT_MISS_MODE_DROP; | ||
640 | struct net_device *netdev = adapter->netdev; | 639 | struct net_device *netdev = adapter->netdev; |
641 | 640 | ||
641 | mode = VPORT_MISS_MODE_DROP; | ||
642 | qlcnic_set_fw_loopback(adapter, 0); | 642 | qlcnic_set_fw_loopback(adapter, 0); |
643 | 643 | ||
644 | if (netdev->flags & IFF_PROMISC) | 644 | if (netdev->flags & IFF_PROMISC) |
@@ -648,12 +648,13 @@ void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter) | |||
648 | 648 | ||
649 | qlcnic_nic_set_promisc(adapter, mode); | 649 | qlcnic_nic_set_promisc(adapter, mode); |
650 | msleep(1000); | 650 | msleep(1000); |
651 | return 0; | ||
651 | } | 652 | } |
652 | 653 | ||
653 | /* | 654 | /* |
654 | * Send the interrupt coalescing parameter set by ethtool to the card. | 655 | * Send the interrupt coalescing parameter set by ethtool to the card. |
655 | */ | 656 | */ |
656 | int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) | 657 | void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter) |
657 | { | 658 | { |
658 | struct qlcnic_nic_req req; | 659 | struct qlcnic_nic_req req; |
659 | int rv; | 660 | int rv; |
@@ -675,10 +676,9 @@ int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) | |||
675 | if (rv != 0) | 676 | if (rv != 0) |
676 | dev_err(&adapter->netdev->dev, | 677 | dev_err(&adapter->netdev->dev, |
677 | "Could not send interrupt coalescing parameters\n"); | 678 | "Could not send interrupt coalescing parameters\n"); |
678 | return rv; | ||
679 | } | 679 | } |
680 | 680 | ||
681 | int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) | 681 | int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int enable) |
682 | { | 682 | { |
683 | struct qlcnic_nic_req req; | 683 | struct qlcnic_nic_req req; |
684 | u64 word; | 684 | u64 word; |
@@ -736,7 +736,7 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) | |||
736 | 736 | ||
737 | #define RSS_HASHTYPE_IP_TCP 0x3 | 737 | #define RSS_HASHTYPE_IP_TCP 0x3 |
738 | 738 | ||
739 | int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) | 739 | int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int enable) |
740 | { | 740 | { |
741 | struct qlcnic_nic_req req; | 741 | struct qlcnic_nic_req req; |
742 | u64 word; | 742 | u64 word; |
@@ -779,7 +779,8 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) | |||
779 | return rv; | 779 | return rv; |
780 | } | 780 | } |
781 | 781 | ||
782 | int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd) | 782 | void qlcnic_82xx_config_ipaddr(struct qlcnic_adapter *adapter, |
783 | __be32 ip, int cmd) | ||
783 | { | 784 | { |
784 | struct qlcnic_nic_req req; | 785 | struct qlcnic_nic_req req; |
785 | struct qlcnic_ipaddr *ipa; | 786 | struct qlcnic_ipaddr *ipa; |
@@ -801,23 +802,19 @@ int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd) | |||
801 | dev_err(&adapter->netdev->dev, | 802 | dev_err(&adapter->netdev->dev, |
802 | "could not notify %s IP 0x%x reuqest\n", | 803 | "could not notify %s IP 0x%x reuqest\n", |
803 | (cmd == QLCNIC_IP_UP) ? "Add" : "Remove", ip); | 804 | (cmd == QLCNIC_IP_UP) ? "Add" : "Remove", ip); |
804 | |||
805 | return rv; | ||
806 | } | 805 | } |
807 | 806 | ||
808 | int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable) | 807 | int qlcnic_82xx_linkevent_request(struct qlcnic_adapter *adapter, int enable) |
809 | { | 808 | { |
810 | struct qlcnic_nic_req req; | 809 | struct qlcnic_nic_req req; |
811 | u64 word; | 810 | u64 word; |
812 | int rv; | 811 | int rv; |
813 | |||
814 | memset(&req, 0, sizeof(struct qlcnic_nic_req)); | 812 | memset(&req, 0, sizeof(struct qlcnic_nic_req)); |
815 | req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); | 813 | req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); |
816 | 814 | ||
817 | word = QLCNIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16); | 815 | word = QLCNIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16); |
818 | req.req_hdr = cpu_to_le64(word); | 816 | req.req_hdr = cpu_to_le64(word); |
819 | req.words[0] = cpu_to_le64(enable | (enable << 8)); | 817 | req.words[0] = cpu_to_le64(enable | (enable << 8)); |
820 | |||
821 | rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); | 818 | rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); |
822 | if (rv != 0) | 819 | if (rv != 0) |
823 | dev_err(&adapter->netdev->dev, | 820 | dev_err(&adapter->netdev->dev, |
@@ -981,8 +978,8 @@ qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off) | |||
981 | return 0; | 978 | return 0; |
982 | } | 979 | } |
983 | 980 | ||
984 | int | 981 | int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, |
985 | qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data) | 982 | u32 data) |
986 | { | 983 | { |
987 | unsigned long flags; | 984 | unsigned long flags; |
988 | int rv; | 985 | int rv; |
@@ -1013,7 +1010,7 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data) | |||
1013 | return -EIO; | 1010 | return -EIO; |
1014 | } | 1011 | } |
1015 | 1012 | ||
1016 | int qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) | 1013 | int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) |
1017 | { | 1014 | { |
1018 | unsigned long flags; | 1015 | unsigned long flags; |
1019 | int rv; | 1016 | int rv; |
@@ -1042,7 +1039,6 @@ int qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) | |||
1042 | return -1; | 1039 | return -1; |
1043 | } | 1040 | } |
1044 | 1041 | ||
1045 | |||
1046 | void __iomem *qlcnic_get_ioaddr(struct qlcnic_hardware_context *ahw, | 1042 | void __iomem *qlcnic_get_ioaddr(struct qlcnic_hardware_context *ahw, |
1047 | u32 offset) | 1043 | u32 offset) |
1048 | { | 1044 | { |
@@ -1268,7 +1264,7 @@ int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) | |||
1268 | return ret; | 1264 | return ret; |
1269 | } | 1265 | } |
1270 | 1266 | ||
1271 | int qlcnic_get_board_info(struct qlcnic_adapter *adapter) | 1267 | int qlcnic_82xx_get_board_info(struct qlcnic_adapter *adapter) |
1272 | { | 1268 | { |
1273 | int offset, board_type, magic; | 1269 | int offset, board_type, magic; |
1274 | struct pci_dev *pdev = adapter->pdev; | 1270 | struct pci_dev *pdev = adapter->pdev; |
@@ -1341,7 +1337,7 @@ qlcnic_wol_supported(struct qlcnic_adapter *adapter) | |||
1341 | return 0; | 1337 | return 0; |
1342 | } | 1338 | } |
1343 | 1339 | ||
1344 | int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) | 1340 | int qlcnic_82xx_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) |
1345 | { | 1341 | { |
1346 | struct qlcnic_nic_req req; | 1342 | struct qlcnic_nic_req req; |
1347 | int rv; | 1343 | int rv; |
@@ -1362,3 +1358,56 @@ int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) | |||
1362 | 1358 | ||
1363 | return rv; | 1359 | return rv; |
1364 | } | 1360 | } |
1361 | |||
1362 | void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter) | ||
1363 | { | ||
1364 | void __iomem *msix_base_addr; | ||
1365 | u32 func; | ||
1366 | u32 msix_base; | ||
1367 | |||
1368 | pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func); | ||
1369 | msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE; | ||
1370 | msix_base = readl(msix_base_addr); | ||
1371 | func = (func - msix_base) / QLCNIC_MSIX_TBL_PGSIZE; | ||
1372 | adapter->ahw->pci_func = func; | ||
1373 | } | ||
1374 | |||
1375 | void qlcnic_82xx_read_crb(struct qlcnic_adapter *adapter, char *buf, | ||
1376 | loff_t offset, size_t size) | ||
1377 | { | ||
1378 | u32 data; | ||
1379 | u64 qmdata; | ||
1380 | |||
1381 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { | ||
1382 | qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata); | ||
1383 | memcpy(buf, &qmdata, size); | ||
1384 | } else { | ||
1385 | data = QLCRD32(adapter, offset); | ||
1386 | memcpy(buf, &data, size); | ||
1387 | } | ||
1388 | } | ||
1389 | |||
1390 | void qlcnic_82xx_write_crb(struct qlcnic_adapter *adapter, char *buf, | ||
1391 | loff_t offset, size_t size) | ||
1392 | { | ||
1393 | u32 data; | ||
1394 | u64 qmdata; | ||
1395 | |||
1396 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { | ||
1397 | memcpy(&qmdata, buf, size); | ||
1398 | qlcnic_pci_camqm_write_2M(adapter, offset, qmdata); | ||
1399 | } else { | ||
1400 | memcpy(&data, buf, size); | ||
1401 | QLCWR32(adapter, offset, data); | ||
1402 | } | ||
1403 | } | ||
1404 | |||
1405 | int qlcnic_82xx_api_lock(struct qlcnic_adapter *adapter) | ||
1406 | { | ||
1407 | return qlcnic_pcie_sem_lock(adapter, 5, 0); | ||
1408 | } | ||
1409 | |||
1410 | void qlcnic_82xx_api_unlock(struct qlcnic_adapter *adapter) | ||
1411 | { | ||
1412 | qlcnic_pcie_sem_unlock(adapter, 5); | ||
1413 | } | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h new file mode 100644 index 000000000000..2b9537d8c167 --- /dev/null +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | |||
@@ -0,0 +1,161 @@ | |||
1 | #ifndef __QLCNIC_HW_H | ||
2 | #define __QLCNIC_HW_H | ||
3 | |||
4 | /* Common registers in 83xx and 82xx */ | ||
5 | enum qlcnic_regs { | ||
6 | QLCNIC_PEG_HALT_STATUS1 = 0, | ||
7 | QLCNIC_PEG_HALT_STATUS2, | ||
8 | QLCNIC_PEG_ALIVE_COUNTER, | ||
9 | QLCNIC_FLASH_LOCK_OWNER, | ||
10 | QLCNIC_FW_CAPABILITIES, | ||
11 | QLCNIC_CRB_DRV_ACTIVE, | ||
12 | QLCNIC_CRB_DEV_STATE, | ||
13 | QLCNIC_CRB_DRV_STATE, | ||
14 | QLCNIC_CRB_DRV_SCRATCH, | ||
15 | QLCNIC_CRB_DEV_PARTITION_INFO, | ||
16 | QLCNIC_CRB_DRV_IDC_VER, | ||
17 | QLCNIC_FW_VERSION_MAJOR, | ||
18 | QLCNIC_FW_VERSION_MINOR, | ||
19 | QLCNIC_FW_VERSION_SUB, | ||
20 | QLCNIC_CRB_DEV_NPAR_STATE, | ||
21 | QLCNIC_FW_IMG_VALID, | ||
22 | QLCNIC_CMDPEG_STATE, | ||
23 | QLCNIC_RCVPEG_STATE, | ||
24 | QLCNIC_ASIC_TEMP, | ||
25 | QLCNIC_FW_API, | ||
26 | QLCNIC_DRV_OP_MODE, | ||
27 | QLCNIC_FLASH_LOCK, | ||
28 | QLCNIC_FLASH_UNLOCK, | ||
29 | }; | ||
30 | |||
31 | #define QLCNIC_CMD_CONFIGURE_IP_ADDR 0x1 | ||
32 | #define QLCNIC_CMD_CONFIG_INTRPT 0x2 | ||
33 | #define QLCNIC_CMD_CREATE_RX_CTX 0x7 | ||
34 | #define QLCNIC_CMD_DESTROY_RX_CTX 0x8 | ||
35 | #define QLCNIC_CMD_CREATE_TX_CTX 0x9 | ||
36 | #define QLCNIC_CMD_DESTROY_TX_CTX 0xa | ||
37 | #define QLCNIC_CMD_CONFIGURE_LRO 0xC | ||
38 | #define QLCNIC_CMD_CONFIGURE_MAC_LEARNING 0xD | ||
39 | #define QLCNIC_CMD_GET_STATISTICS 0xF | ||
40 | #define QLCNIC_CMD_INTRPT_TEST 0x11 | ||
41 | #define QLCNIC_CMD_SET_MTU 0x12 | ||
42 | #define QLCNIC_CMD_READ_PHY 0x13 | ||
43 | #define QLCNIC_CMD_WRITE_PHY 0x14 | ||
44 | #define QLCNIC_CMD_READ_HW_REG 0x15 | ||
45 | #define QLCNIC_CMD_GET_FLOW_CTL 0x16 | ||
46 | #define QLCNIC_CMD_SET_FLOW_CTL 0x17 | ||
47 | #define QLCNIC_CMD_READ_MAX_MTU 0x18 | ||
48 | #define QLCNIC_CMD_READ_MAX_LRO 0x19 | ||
49 | #define QLCNIC_CMD_MAC_ADDRESS 0x1f | ||
50 | #define QLCNIC_CMD_GET_PCI_INFO 0x20 | ||
51 | #define QLCNIC_CMD_GET_NIC_INFO 0x21 | ||
52 | #define QLCNIC_CMD_SET_NIC_INFO 0x22 | ||
53 | #define QLCNIC_CMD_GET_ESWITCH_CAPABILITY 0x24 | ||
54 | #define QLCNIC_CMD_TOGGLE_ESWITCH 0x25 | ||
55 | #define QLCNIC_CMD_GET_ESWITCH_STATUS 0x26 | ||
56 | #define QLCNIC_CMD_SET_PORTMIRRORING 0x27 | ||
57 | #define QLCNIC_CMD_CONFIGURE_ESWITCH 0x28 | ||
58 | #define QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG 0x29 | ||
59 | #define QLCNIC_CMD_GET_ESWITCH_STATS 0x2a | ||
60 | #define QLCNIC_CMD_CONFIG_PORT 0x2e | ||
61 | #define QLCNIC_CMD_TEMP_SIZE 0x2f | ||
62 | #define QLCNIC_CMD_GET_TEMP_HDR 0x30 | ||
63 | #define QLCNIC_CMD_GET_MAC_STATS 0x37 | ||
64 | #define QLCNIC_CMD_SET_DRV_VER 0x38 | ||
65 | #define QLCNIC_CMD_CONFIGURE_RSS 0x41 | ||
66 | #define QLCNIC_CMD_CONFIG_INTR_COAL 0x43 | ||
67 | #define QLCNIC_CMD_CONFIGURE_LED 0x44 | ||
68 | #define QLCNIC_CMD_CONFIG_MAC_VLAN 0x45 | ||
69 | #define QLCNIC_CMD_GET_LINK_EVENT 0x48 | ||
70 | #define QLCNIC_CMD_CONFIGURE_MAC_RX_MODE 0x49 | ||
71 | #define QLCNIC_CMD_CONFIGURE_HW_LRO 0x4A | ||
72 | #define QLCNIC_CMD_INIT_NIC_FUNC 0x60 | ||
73 | #define QLCNIC_CMD_STOP_NIC_FUNC 0x61 | ||
74 | #define QLCNIC_CMD_IDC_ACK 0x63 | ||
75 | #define QLCNIC_CMD_SET_PORT_CONFIG 0x66 | ||
76 | #define QLCNIC_CMD_GET_PORT_CONFIG 0x67 | ||
77 | #define QLCNIC_CMD_GET_LINK_STATUS 0x68 | ||
78 | #define QLCNIC_CMD_SET_LED_CONFIG 0x69 | ||
79 | #define QLCNIC_CMD_GET_LED_CONFIG 0x6A | ||
80 | |||
81 | #define QLCNIC_INTRPT_INTX 1 | ||
82 | #define QLCNIC_INTRPT_MSIX 3 | ||
83 | #define QLCNIC_INTRPT_ADD 1 | ||
84 | #define QLCNIC_INTRPT_DEL 2 | ||
85 | |||
86 | #define QLCNIC_GET_CURRENT_MAC 1 | ||
87 | #define QLCNIC_SET_STATION_MAC 2 | ||
88 | #define QLCNIC_GET_DEFAULT_MAC 3 | ||
89 | #define QLCNIC_GET_FAC_DEF_MAC 4 | ||
90 | #define QLCNIC_SET_FAC_DEF_MAC 5 | ||
91 | |||
92 | #define QLCNIC_MBX_LINK_EVENT 0x8001 | ||
93 | #define QLCNIC_MBX_COMP_EVENT 0x8100 | ||
94 | #define QLCNIC_MBX_REQUEST_EVENT 0x8101 | ||
95 | #define QLCNIC_MBX_TIME_EXTEND_EVENT 0x8102 | ||
96 | #define QLCNIC_MBX_SFP_INSERT_EVENT 0x8130 | ||
97 | #define QLCNIC_MBX_SFP_REMOVE_EVENT 0x8131 | ||
98 | |||
99 | struct qlcnic_mailbox_metadata { | ||
100 | u32 cmd; | ||
101 | u32 in_args; | ||
102 | u32 out_args; | ||
103 | }; | ||
104 | |||
105 | #define QLCNIC_MBX_RSP_OK 1 | ||
106 | #define QLCNIC_MBX_PORT_RSP_OK 0x1a | ||
107 | |||
108 | struct qlcnic_pci_info; | ||
109 | struct qlcnic_info; | ||
110 | struct qlcnic_cmd_args; | ||
111 | struct ethtool_stats; | ||
112 | struct pci_device_id; | ||
113 | struct qlcnic_host_sds_ring; | ||
114 | struct qlcnic_host_tx_ring; | ||
115 | struct qlcnic_host_tx_ring; | ||
116 | struct qlcnic_hardware_context; | ||
117 | struct qlcnic_adapter; | ||
118 | |||
119 | int qlcnic_82xx_start_firmware(struct qlcnic_adapter *); | ||
120 | int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong); | ||
121 | int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *, ulong, u32); | ||
122 | int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int); | ||
123 | int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32); | ||
124 | int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, | ||
125 | struct net_device *netdev); | ||
126 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, | ||
127 | u64 *uaddr, __le16 vlan_id); | ||
128 | void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); | ||
129 | int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int); | ||
130 | void qlcnic_82xx_config_ipaddr(struct qlcnic_adapter *adapter, | ||
131 | __be32, int); | ||
132 | int qlcnic_82xx_linkevent_request(struct qlcnic_adapter *adapter, int); | ||
133 | void qlcnic_82xx_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); | ||
134 | int qlcnic_82xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8); | ||
135 | int qlcnic_82xx_set_lb_mode(struct qlcnic_adapter *, u8); | ||
136 | void qlcnic_82xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t); | ||
137 | void qlcnic_82xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t); | ||
138 | void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *, u32); | ||
139 | int qlcnic_82xx_setup_intr(struct qlcnic_adapter *, u8); | ||
140 | irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *); | ||
141 | int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter, | ||
142 | struct qlcnic_cmd_args *); | ||
143 | int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *); | ||
144 | int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *, | ||
145 | struct qlcnic_host_tx_ring *tx_ring, int); | ||
146 | int qlcnic_82xx_sre_macaddr_change(struct qlcnic_adapter *, u8 *, __le16, u8); | ||
147 | int qlcnic_82xx_get_mac_address(struct qlcnic_adapter *, u8*); | ||
148 | int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8); | ||
149 | int qlcnic_82xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); | ||
150 | int qlcnic_82xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*); | ||
151 | int qlcnic_82xx_alloc_mbx_args(struct qlcnic_cmd_args *, | ||
152 | struct qlcnic_adapter *, u32); | ||
153 | int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *, ulong, u32); | ||
154 | int qlcnic_82xx_get_board_info(struct qlcnic_adapter *); | ||
155 | int qlcnic_82xx_config_led(struct qlcnic_adapter *, u32, u32); | ||
156 | void qlcnic_82xx_get_func_no(struct qlcnic_adapter *); | ||
157 | int qlcnic_82xx_api_lock(struct qlcnic_adapter *); | ||
158 | void qlcnic_82xx_api_unlock(struct qlcnic_adapter *); | ||
159 | void qlcnic_82xx_napi_enable(struct qlcnic_adapter *); | ||
160 | void qlcnic_82xx_napi_disable(struct qlcnic_adapter *); | ||
161 | #endif /* __QLCNIC_HW_H_ */ | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 6f82812d0fab..8d9202fe2dee 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -95,14 +95,14 @@ | |||
95 | #define STATUS_CKSUM_LOOP 0 | 95 | #define STATUS_CKSUM_LOOP 0 |
96 | #define STATUS_CKSUM_OK 2 | 96 | #define STATUS_CKSUM_OK 2 |
97 | 97 | ||
98 | static void qlcnic_change_filter(struct qlcnic_adapter *adapter, | 98 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, u64 *uaddr, |
99 | u64 uaddr, __le16 vlan_id, | 99 | __le16 vlan_id) |
100 | struct qlcnic_host_tx_ring *tx_ring) | ||
101 | { | 100 | { |
102 | struct cmd_desc_type0 *hwdesc; | 101 | struct cmd_desc_type0 *hwdesc; |
103 | struct qlcnic_nic_req *req; | 102 | struct qlcnic_nic_req *req; |
104 | struct qlcnic_mac_req *mac_req; | 103 | struct qlcnic_mac_req *mac_req; |
105 | struct qlcnic_vlan_req *vlan_req; | 104 | struct qlcnic_vlan_req *vlan_req; |
105 | struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring; | ||
106 | u32 producer; | 106 | u32 producer; |
107 | u64 word; | 107 | u64 word; |
108 | 108 | ||
@@ -132,21 +132,21 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
132 | struct cmd_desc_type0 *first_desc, | 132 | struct cmd_desc_type0 *first_desc, |
133 | struct sk_buff *skb) | 133 | struct sk_buff *skb) |
134 | { | 134 | { |
135 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); | ||
136 | struct qlcnic_filter *fil, *tmp_fil; | 135 | struct qlcnic_filter *fil, *tmp_fil; |
137 | struct hlist_node *tmp_hnode, *n; | 136 | struct hlist_node *tmp_hnode, *n; |
138 | struct hlist_head *head; | 137 | struct hlist_head *head; |
138 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); | ||
139 | u64 src_addr = 0; | 139 | u64 src_addr = 0; |
140 | __le16 vlan_id = 0; | 140 | __le16 vlan_id = 0; |
141 | u8 hindex; | 141 | u8 hindex; |
142 | 142 | ||
143 | if (ether_addr_equal(phdr->h_source, adapter->mac_addr)) | 143 | if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) |
144 | return; | 144 | return; |
145 | 145 | ||
146 | if (adapter->fhash.fnum >= adapter->fhash.fmax) | 146 | if (adapter->fhash.fnum >= adapter->fhash.fmax) |
147 | return; | 147 | return; |
148 | 148 | ||
149 | /* Only NPAR capable devices support vlan based learning*/ | 149 | /* Only NPAR capable devices support vlan based learning */ |
150 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) | 150 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED) |
151 | vlan_id = first_desc->vlan_TCI; | 151 | vlan_id = first_desc->vlan_TCI; |
152 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | 152 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); |
@@ -155,11 +155,10 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
155 | 155 | ||
156 | hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { | 156 | hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { |
157 | if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && | 157 | if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && |
158 | tmp_fil->vlan_id == vlan_id) { | 158 | tmp_fil->vlan_id == vlan_id) { |
159 | |||
160 | if (jiffies > (QLCNIC_READD_AGE * HZ + tmp_fil->ftime)) | 159 | if (jiffies > (QLCNIC_READD_AGE * HZ + tmp_fil->ftime)) |
161 | qlcnic_change_filter(adapter, src_addr, vlan_id, | 160 | qlcnic_change_filter(adapter, &src_addr, |
162 | tx_ring); | 161 | vlan_id); |
163 | tmp_fil->ftime = jiffies; | 162 | tmp_fil->ftime = jiffies; |
164 | return; | 163 | return; |
165 | } | 164 | } |
@@ -169,17 +168,13 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
169 | if (!fil) | 168 | if (!fil) |
170 | return; | 169 | return; |
171 | 170 | ||
172 | qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring); | 171 | qlcnic_change_filter(adapter, &src_addr, vlan_id); |
173 | |||
174 | fil->ftime = jiffies; | 172 | fil->ftime = jiffies; |
175 | fil->vlan_id = vlan_id; | 173 | fil->vlan_id = vlan_id; |
176 | memcpy(fil->faddr, &src_addr, ETH_ALEN); | 174 | memcpy(fil->faddr, &src_addr, ETH_ALEN); |
177 | |||
178 | spin_lock(&adapter->mac_learn_lock); | 175 | spin_lock(&adapter->mac_learn_lock); |
179 | |||
180 | hlist_add_head(&(fil->fnode), head); | 176 | hlist_add_head(&(fil->fnode), head); |
181 | adapter->fhash.fnum++; | 177 | adapter->fhash.fnum++; |
182 | |||
183 | spin_unlock(&adapter->mac_learn_lock); | 178 | spin_unlock(&adapter->mac_learn_lock); |
184 | } | 179 | } |
185 | 180 | ||
@@ -492,7 +487,8 @@ drop_packet: | |||
492 | return NETDEV_TX_OK; | 487 | return NETDEV_TX_OK; |
493 | } | 488 | } |
494 | 489 | ||
495 | void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) | 490 | static void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, |
491 | int linkup) | ||
496 | { | 492 | { |
497 | struct net_device *netdev = adapter->netdev; | 493 | struct net_device *netdev = adapter->netdev; |
498 | 494 | ||
@@ -1180,7 +1176,7 @@ static void qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, int ring, | |||
1180 | return; | 1176 | return; |
1181 | } | 1177 | } |
1182 | 1178 | ||
1183 | void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) | 1179 | void qlcnic_82xx_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) |
1184 | { | 1180 | { |
1185 | struct qlcnic_adapter *adapter = sds_ring->adapter; | 1181 | struct qlcnic_adapter *adapter = sds_ring->adapter; |
1186 | struct status_desc *desc; | 1182 | struct status_desc *desc; |
@@ -1217,26 +1213,8 @@ void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) | |||
1217 | writel(consumer, sds_ring->crb_sts_consumer); | 1213 | writel(consumer, sds_ring->crb_sts_consumer); |
1218 | } | 1214 | } |
1219 | 1215 | ||
1220 | void qlcnic_fetch_mac(u32 off1, u32 off2, u8 alt_mac, u8 *mac) | 1216 | int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, |
1221 | { | 1217 | struct net_device *netdev) |
1222 | u32 mac_low, mac_high; | ||
1223 | int i; | ||
1224 | |||
1225 | mac_low = off1; | ||
1226 | mac_high = off2; | ||
1227 | |||
1228 | if (alt_mac) { | ||
1229 | mac_low |= (mac_low >> 16) | (mac_high << 16); | ||
1230 | mac_high >>= 16; | ||
1231 | } | ||
1232 | |||
1233 | for (i = 0; i < 2; i++) | ||
1234 | mac[i] = (u8)(mac_high >> ((1 - i) * 8)); | ||
1235 | for (i = 2; i < 6; i++) | ||
1236 | mac[i] = (u8)(mac_low >> ((5 - i) * 8)); | ||
1237 | } | ||
1238 | |||
1239 | int qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
1240 | { | 1218 | { |
1241 | int ring, max_sds_rings; | 1219 | int ring, max_sds_rings; |
1242 | struct qlcnic_host_sds_ring *sds_ring; | 1220 | struct qlcnic_host_sds_ring *sds_ring; |
@@ -1275,7 +1253,7 @@ void qlcnic_napi_del(struct qlcnic_adapter *adapter) | |||
1275 | qlcnic_free_sds_rings(adapter->recv_ctx); | 1253 | qlcnic_free_sds_rings(adapter->recv_ctx); |
1276 | } | 1254 | } |
1277 | 1255 | ||
1278 | void qlcnic_napi_enable(struct qlcnic_adapter *adapter) | 1256 | void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter) |
1279 | { | 1257 | { |
1280 | int ring; | 1258 | int ring; |
1281 | struct qlcnic_host_sds_ring *sds_ring; | 1259 | struct qlcnic_host_sds_ring *sds_ring; |
@@ -1291,7 +1269,7 @@ void qlcnic_napi_enable(struct qlcnic_adapter *adapter) | |||
1291 | } | 1269 | } |
1292 | } | 1270 | } |
1293 | 1271 | ||
1294 | void qlcnic_napi_disable(struct qlcnic_adapter *adapter) | 1272 | void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter) |
1295 | { | 1273 | { |
1296 | int ring; | 1274 | int ring; |
1297 | struct qlcnic_host_sds_ring *sds_ring; | 1275 | struct qlcnic_host_sds_ring *sds_ring; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index d833f5927891..70d325c19dcf 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -120,6 +120,32 @@ static const u32 msi_tgt_status[8] = { | |||
120 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 | 120 | ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static const u32 qlcnic_reg_tbl[] = { | ||
124 | 0x1B20A8, /* PEG_HALT_STAT1 */ | ||
125 | 0x1B20AC, /* PEG_HALT_STAT2 */ | ||
126 | 0x1B20B0, /* FW_HEARTBEAT */ | ||
127 | 0x1B2100, /* LOCK ID */ | ||
128 | 0x1B2128, /* FW_CAPABILITIES */ | ||
129 | 0x1B2138, /* drv active */ | ||
130 | 0x1B2140, /* dev state */ | ||
131 | 0x1B2144, /* drv state */ | ||
132 | 0x1B2148, /* drv scratch */ | ||
133 | 0x1B214C, /* dev partition info */ | ||
134 | 0x1B2174, /* drv idc ver */ | ||
135 | 0x1B2150, /* fw version major */ | ||
136 | 0x1B2154, /* fw version minor */ | ||
137 | 0x1B2158, /* fw version sub */ | ||
138 | 0x1B219C, /* npar state */ | ||
139 | 0x1B21FC, /* FW_IMG_VALID */ | ||
140 | 0x1B2250, /* CMD_PEG_STATE */ | ||
141 | 0x1B233C, /* RCV_PEG_STATE */ | ||
142 | 0x1B23B4, /* ASIC TEMP */ | ||
143 | 0x1B216C, /* FW api */ | ||
144 | 0x1B2170, /* drv op mode */ | ||
145 | 0x13C010, /* flash lock */ | ||
146 | 0x13C014, /* flash unlock */ | ||
147 | }; | ||
148 | |||
123 | static const struct qlcnic_board_info qlcnic_boards[] = { | 149 | static const struct qlcnic_board_info qlcnic_boards[] = { |
124 | {0x1077, 0x8020, 0x1077, 0x203, | 150 | {0x1077, 0x8020, 0x1077, 0x203, |
125 | "8200 Series Single Port 10GbE Converged Network Adapter" | 151 | "8200 Series Single Port 10GbE Converged Network Adapter" |
@@ -164,11 +190,6 @@ void qlcnic_free_sds_rings(struct qlcnic_recv_context *recv_ctx) | |||
164 | recv_ctx->sds_rings = NULL; | 190 | recv_ctx->sds_rings = NULL; |
165 | } | 191 | } |
166 | 192 | ||
167 | static void qlcnic_clear_stats(struct qlcnic_adapter *adapter) | ||
168 | { | ||
169 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | ||
170 | } | ||
171 | |||
172 | static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable) | 193 | static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable) |
173 | { | 194 | { |
174 | u32 control; | 195 | u32 control; |
@@ -243,6 +264,14 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) | |||
243 | return 0; | 264 | return 0; |
244 | } | 265 | } |
245 | 266 | ||
267 | static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter) | ||
268 | { | ||
269 | while (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) | ||
270 | usleep_range(10000, 11000); | ||
271 | |||
272 | cancel_delayed_work_sync(&adapter->fw_work); | ||
273 | } | ||
274 | |||
246 | static const struct net_device_ops qlcnic_netdev_ops = { | 275 | static const struct net_device_ops qlcnic_netdev_ops = { |
247 | .ndo_open = qlcnic_open, | 276 | .ndo_open = qlcnic_open, |
248 | .ndo_stop = qlcnic_close, | 277 | .ndo_stop = qlcnic_close, |
@@ -267,15 +296,54 @@ static const struct net_device_ops qlcnic_netdev_failed_ops = { | |||
267 | }; | 296 | }; |
268 | 297 | ||
269 | static struct qlcnic_nic_template qlcnic_ops = { | 298 | static struct qlcnic_nic_template qlcnic_ops = { |
270 | .config_bridged_mode = qlcnic_config_bridged_mode, | 299 | .config_bridged_mode = qlcnic_config_bridged_mode, |
271 | .config_led = qlcnic_config_led, | 300 | .config_led = qlcnic_82xx_config_led, |
272 | .start_firmware = qlcnic_start_firmware | 301 | .start_firmware = qlcnic_82xx_start_firmware, |
302 | .request_reset = qlcnic_82xx_dev_request_reset, | ||
303 | .cancel_idc_work = qlcnic_82xx_cancel_idc_work, | ||
304 | .napi_add = qlcnic_82xx_napi_add, | ||
305 | .config_ipaddr = qlcnic_82xx_config_ipaddr, | ||
306 | .clear_legacy_intr = qlcnic_82xx_clear_legacy_intr, | ||
307 | }; | ||
308 | |||
309 | struct qlcnic_nic_template qlcnic_vf_ops = { | ||
310 | .config_bridged_mode = qlcnicvf_config_bridged_mode, | ||
311 | .config_led = qlcnicvf_config_led, | ||
312 | .start_firmware = qlcnicvf_start_firmware | ||
273 | }; | 313 | }; |
274 | 314 | ||
275 | static struct qlcnic_nic_template qlcnic_vf_ops = { | 315 | static struct qlcnic_hardware_ops qlcnic_hw_ops = { |
276 | .config_bridged_mode = qlcnicvf_config_bridged_mode, | 316 | .read_crb = qlcnic_82xx_read_crb, |
277 | .config_led = qlcnicvf_config_led, | 317 | .write_crb = qlcnic_82xx_write_crb, |
278 | .start_firmware = qlcnicvf_start_firmware | 318 | .read_reg = qlcnic_82xx_hw_read_wx_2M, |
319 | .write_reg = qlcnic_82xx_hw_write_wx_2M, | ||
320 | .get_mac_address = qlcnic_82xx_get_mac_address, | ||
321 | .setup_intr = qlcnic_82xx_setup_intr, | ||
322 | .alloc_mbx_args = qlcnic_82xx_alloc_mbx_args, | ||
323 | .mbx_cmd = qlcnic_82xx_issue_cmd, | ||
324 | .get_func_no = qlcnic_82xx_get_func_no, | ||
325 | .api_lock = qlcnic_82xx_api_lock, | ||
326 | .api_unlock = qlcnic_82xx_api_unlock, | ||
327 | .add_sysfs = qlcnic_82xx_add_sysfs, | ||
328 | .remove_sysfs = qlcnic_82xx_remove_sysfs, | ||
329 | .process_lb_rcv_ring_diag = qlcnic_82xx_process_rcv_ring_diag, | ||
330 | .create_rx_ctx = qlcnic_82xx_fw_cmd_create_rx_ctx, | ||
331 | .create_tx_ctx = qlcnic_82xx_fw_cmd_create_tx_ctx, | ||
332 | .setup_link_event = qlcnic_82xx_linkevent_request, | ||
333 | .get_nic_info = qlcnic_82xx_get_nic_info, | ||
334 | .get_pci_info = qlcnic_82xx_get_pci_info, | ||
335 | .set_nic_info = qlcnic_82xx_set_nic_info, | ||
336 | .change_macvlan = qlcnic_82xx_sre_macaddr_change, | ||
337 | .napi_enable = qlcnic_82xx_napi_enable, | ||
338 | .napi_disable = qlcnic_82xx_napi_disable, | ||
339 | .config_intr_coal = qlcnic_82xx_config_intr_coalesce, | ||
340 | .config_rss = qlcnic_82xx_config_rss, | ||
341 | .config_hw_lro = qlcnic_82xx_config_hw_lro, | ||
342 | .config_loopback = qlcnic_82xx_set_lb_mode, | ||
343 | .clear_loopback = qlcnic_82xx_clear_lb_mode, | ||
344 | .config_promisc_mode = qlcnic_82xx_nic_set_promisc, | ||
345 | .change_l2_filter = qlcnic_82xx_change_filter, | ||
346 | .get_board_info = qlcnic_82xx_get_board_info, | ||
279 | }; | 347 | }; |
280 | 348 | ||
281 | static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) | 349 | static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) |
@@ -338,21 +406,25 @@ static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) | |||
338 | adapter->msix_entries[0].vector = pdev->irq; | 406 | adapter->msix_entries[0].vector = pdev->irq; |
339 | } | 407 | } |
340 | 408 | ||
341 | static void | 409 | int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) |
342 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) | ||
343 | { | 410 | { |
344 | int num_msix; | 411 | int num_msix, err; |
345 | 412 | ||
346 | if (adapter->ahw->msix_supported) { | 413 | if (!num_intr) |
414 | num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS; | ||
415 | |||
416 | if (adapter->ahw->msix_supported) | ||
347 | num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(), | 417 | num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(), |
348 | QLCNIC_DEF_NUM_STS_DESC_RINGS)); | 418 | num_intr)); |
349 | } else | 419 | else |
350 | num_msix = 1; | 420 | num_msix = 1; |
351 | 421 | ||
352 | if (!qlcnic_enable_msix(adapter, num_msix)) | 422 | err = qlcnic_enable_msix(adapter, num_msix); |
353 | return; | 423 | if (err == -ENOMEM || !err) |
424 | return err; | ||
354 | 425 | ||
355 | qlcnic_enable_msi_legacy(adapter); | 426 | qlcnic_enable_msi_legacy(adapter); |
427 | return 0; | ||
356 | } | 428 | } |
357 | 429 | ||
358 | static void | 430 | static void |
@@ -371,6 +443,34 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
371 | iounmap(adapter->ahw->pci_base0); | 443 | iounmap(adapter->ahw->pci_base0); |
372 | } | 444 | } |
373 | 445 | ||
446 | static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) | ||
447 | { | ||
448 | struct qlcnic_pci_info *pci_info; | ||
449 | int ret; | ||
450 | |||
451 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
452 | switch (adapter->ahw->port_type) { | ||
453 | case QLCNIC_GBE: | ||
454 | adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_GBE_PORTS; | ||
455 | break; | ||
456 | case QLCNIC_XGBE: | ||
457 | adapter->ahw->act_pci_func = QLCNIC_NIU_MAX_XG_PORTS; | ||
458 | break; | ||
459 | } | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) | ||
464 | return 0; | ||
465 | |||
466 | pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); | ||
467 | if (!pci_info) | ||
468 | return -ENOMEM; | ||
469 | |||
470 | ret = qlcnic_get_pci_info(adapter, pci_info); | ||
471 | kfree(pci_info); | ||
472 | return ret; | ||
473 | } | ||
374 | static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | 474 | static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) |
375 | { | 475 | { |
376 | struct qlcnic_pci_info *pci_info; | 476 | struct qlcnic_pci_info *pci_info; |
@@ -547,6 +647,7 @@ static int qlcnic_setup_pci_map(struct pci_dev *pdev, | |||
547 | } | 647 | } |
548 | 648 | ||
549 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); | 649 | dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); |
650 | |||
550 | ahw->pci_base0 = mem_ptr0; | 651 | ahw->pci_base0 = mem_ptr0; |
551 | ahw->pci_len0 = pci_len0; | 652 | ahw->pci_len0 = pci_len0; |
552 | offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func)); | 653 | offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func)); |
@@ -944,8 +1045,7 @@ qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) | |||
944 | return err; | 1045 | return err; |
945 | } | 1046 | } |
946 | 1047 | ||
947 | static int | 1048 | int qlcnic_82xx_start_firmware(struct qlcnic_adapter *adapter) |
948 | qlcnic_start_firmware(struct qlcnic_adapter *adapter) | ||
949 | { | 1049 | { |
950 | int err; | 1050 | int err; |
951 | 1051 | ||
@@ -1493,13 +1593,13 @@ qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count) | |||
1493 | return -ENOMEM; | 1593 | return -ENOMEM; |
1494 | } | 1594 | } |
1495 | 1595 | ||
1496 | static int | 1596 | static int __devinit |
1497 | qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 1597 | qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
1498 | { | 1598 | { |
1499 | struct net_device *netdev = NULL; | 1599 | struct net_device *netdev = NULL; |
1500 | struct qlcnic_adapter *adapter = NULL; | 1600 | struct qlcnic_adapter *adapter = NULL; |
1601 | struct qlcnic_hardware_context *ahw; | ||
1501 | int err, pci_using_dac = -1; | 1602 | int err, pci_using_dac = -1; |
1502 | uint8_t revision_id; | ||
1503 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN]; | 1603 | char board_name[QLCNIC_MAX_BOARD_NAME_LEN]; |
1504 | 1604 | ||
1505 | err = pci_enable_device(pdev); | 1605 | err = pci_enable_device(pdev); |
@@ -1522,10 +1622,23 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1522 | pci_set_master(pdev); | 1622 | pci_set_master(pdev); |
1523 | pci_enable_pcie_error_reporting(pdev); | 1623 | pci_enable_pcie_error_reporting(pdev); |
1524 | 1624 | ||
1625 | ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); | ||
1626 | if (!ahw) | ||
1627 | goto err_out_free_res; | ||
1628 | |||
1629 | if (ent->device == PCI_DEVICE_ID_QLOGIC_QLE824X) { | ||
1630 | ahw->hw_ops = &qlcnic_hw_ops; | ||
1631 | ahw->reg_tbl = (u32 *)qlcnic_reg_tbl; | ||
1632 | } | ||
1633 | |||
1634 | err = qlcnic_setup_pci_map(pdev, ahw); | ||
1635 | if (err) | ||
1636 | goto err_out_free_hw_res; | ||
1637 | |||
1525 | netdev = alloc_etherdev(sizeof(struct qlcnic_adapter)); | 1638 | netdev = alloc_etherdev(sizeof(struct qlcnic_adapter)); |
1526 | if (!netdev) { | 1639 | if (!netdev) { |
1527 | err = -ENOMEM; | 1640 | err = -ENOMEM; |
1528 | goto err_out_free_res; | 1641 | goto err_out_iounmap; |
1529 | } | 1642 | } |
1530 | 1643 | ||
1531 | SET_NETDEV_DEV(netdev, &pdev->dev); | 1644 | SET_NETDEV_DEV(netdev, &pdev->dev); |
@@ -1539,9 +1652,9 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1539 | goto err_out_free_netdev; | 1652 | goto err_out_free_netdev; |
1540 | 1653 | ||
1541 | adapter->dev_rst_time = jiffies; | 1654 | adapter->dev_rst_time = jiffies; |
1542 | revision_id = pdev->revision; | 1655 | adapter->ahw->revision_id = pdev->revision; |
1543 | adapter->ahw->revision_id = revision_id; | ||
1544 | adapter->mac_learn = qlcnic_mac_learn; | 1656 | adapter->mac_learn = qlcnic_mac_learn; |
1657 | adapter->max_drv_tx_rings = 1; | ||
1545 | 1658 | ||
1546 | rwlock_init(&adapter->ahw->crb_lock); | 1659 | rwlock_init(&adapter->ahw->crb_lock); |
1547 | mutex_init(&adapter->ahw->mem_lock); | 1660 | mutex_init(&adapter->ahw->mem_lock); |
@@ -1549,31 +1662,20 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1549 | spin_lock_init(&adapter->tx_clean_lock); | 1662 | spin_lock_init(&adapter->tx_clean_lock); |
1550 | INIT_LIST_HEAD(&adapter->mac_list); | 1663 | INIT_LIST_HEAD(&adapter->mac_list); |
1551 | 1664 | ||
1552 | err = qlcnic_setup_pci_map(pdev, adapter->ahw); | 1665 | if (qlcnic_82xx_check(adapter)) { |
1553 | if (err) | 1666 | qlcnic_check_vf(adapter); |
1554 | goto err_out_free_hw; | 1667 | adapter->portnum = adapter->ahw->pci_func; |
1555 | qlcnic_check_vf(adapter); | 1668 | err = qlcnic_start_firmware(adapter); |
1556 | 1669 | if (err) { | |
1557 | /* This will be reset for mezz cards */ | 1670 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); |
1558 | adapter->portnum = adapter->ahw->pci_func; | 1671 | goto err_out_free_hw; |
1559 | 1672 | } | |
1560 | err = qlcnic_get_board_info(adapter); | ||
1561 | if (err) { | ||
1562 | dev_err(&pdev->dev, "Error getting board config info.\n"); | ||
1563 | goto err_out_iounmap; | ||
1564 | } | ||
1565 | |||
1566 | err = qlcnic_setup_idc_param(adapter); | ||
1567 | if (err) | ||
1568 | goto err_out_iounmap; | ||
1569 | 1673 | ||
1570 | adapter->flags |= QLCNIC_NEED_FLR; | 1674 | err = qlcnic_setup_idc_param(adapter); |
1675 | if (err) | ||
1676 | goto err_out_free_hw; | ||
1571 | 1677 | ||
1572 | err = adapter->nic_ops->start_firmware(adapter); | 1678 | adapter->flags |= QLCNIC_NEED_FLR; |
1573 | if (err) { | ||
1574 | dev_err(&pdev->dev, "Loading fw failed. Please Reboot\n" | ||
1575 | "\t\tIf reboot doesn't help, try flashing the card\n"); | ||
1576 | goto err_out_maintenance_mode; | ||
1577 | } | 1679 | } |
1578 | 1680 | ||
1579 | if (qlcnic_read_mac_addr(adapter)) | 1681 | if (qlcnic_read_mac_addr(adapter)) |
@@ -1585,18 +1687,18 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1585 | module_name(THIS_MODULE), | 1687 | module_name(THIS_MODULE), |
1586 | board_name, adapter->ahw->revision_id); | 1688 | board_name, adapter->ahw->revision_id); |
1587 | } | 1689 | } |
1588 | |||
1589 | qlcnic_clear_stats(adapter); | ||
1590 | |||
1591 | err = qlcnic_alloc_msix_entries(adapter, adapter->ahw->max_rx_ques); | 1690 | err = qlcnic_alloc_msix_entries(adapter, adapter->ahw->max_rx_ques); |
1592 | if (err) | 1691 | if (err) |
1593 | goto err_out_decr_ref; | 1692 | goto err_out_disable_msi; |
1693 | |||
1694 | err = qlcnic_setup_intr(adapter, 0); | ||
1695 | if (err) | ||
1696 | goto err_out_disable_msi; | ||
1594 | 1697 | ||
1595 | qlcnic_setup_intr(adapter); | ||
1596 | 1698 | ||
1597 | err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); | 1699 | err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac); |
1598 | if (err) | 1700 | if (err) |
1599 | goto err_out_disable_msi; | 1701 | goto err_out_disable_mbx_intr; |
1600 | 1702 | ||
1601 | pci_set_drvdata(pdev, adapter); | 1703 | pci_set_drvdata(pdev, adapter); |
1602 | 1704 | ||
@@ -1615,29 +1717,35 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1615 | break; | 1717 | break; |
1616 | } | 1718 | } |
1617 | 1719 | ||
1720 | if (qlcnic_get_act_pci_func(adapter)) | ||
1721 | goto err_out_disable_mbx_intr; | ||
1722 | |||
1618 | if (adapter->mac_learn) | 1723 | if (adapter->mac_learn) |
1619 | qlcnic_alloc_lb_filters_mem(adapter); | 1724 | qlcnic_alloc_lb_filters_mem(adapter); |
1620 | 1725 | ||
1621 | qlcnic_create_diag_entries(adapter); | 1726 | qlcnic_add_sysfs(adapter); |
1622 | 1727 | ||
1623 | return 0; | 1728 | return 0; |
1624 | 1729 | ||
1730 | err_out_disable_mbx_intr: | ||
1731 | |||
1625 | err_out_disable_msi: | 1732 | err_out_disable_msi: |
1626 | qlcnic_teardown_intr(adapter); | 1733 | qlcnic_teardown_intr(adapter); |
1627 | kfree(adapter->msix_entries); | 1734 | qlcnic_cancel_idc_work(adapter); |
1628 | |||
1629 | err_out_decr_ref: | ||
1630 | qlcnic_clr_all_drv_state(adapter, 0); | 1735 | qlcnic_clr_all_drv_state(adapter, 0); |
1631 | 1736 | ||
1632 | err_out_iounmap: | ||
1633 | qlcnic_cleanup_pci_map(adapter); | ||
1634 | |||
1635 | err_out_free_hw: | 1737 | err_out_free_hw: |
1636 | qlcnic_free_adapter_resources(adapter); | 1738 | qlcnic_free_adapter_resources(adapter); |
1637 | 1739 | ||
1638 | err_out_free_netdev: | 1740 | err_out_free_netdev: |
1639 | free_netdev(netdev); | 1741 | free_netdev(netdev); |
1640 | 1742 | ||
1743 | err_out_iounmap: | ||
1744 | qlcnic_cleanup_pci_map(adapter); | ||
1745 | |||
1746 | err_out_free_hw_res: | ||
1747 | kfree(ahw); | ||
1748 | |||
1641 | err_out_free_res: | 1749 | err_out_free_res: |
1642 | pci_release_regions(pdev); | 1750 | pci_release_regions(pdev); |
1643 | 1751 | ||
@@ -1645,18 +1753,6 @@ err_out_disable_pdev: | |||
1645 | pci_set_drvdata(pdev, NULL); | 1753 | pci_set_drvdata(pdev, NULL); |
1646 | pci_disable_device(pdev); | 1754 | pci_disable_device(pdev); |
1647 | return err; | 1755 | return err; |
1648 | |||
1649 | err_out_maintenance_mode: | ||
1650 | netdev->netdev_ops = &qlcnic_netdev_failed_ops; | ||
1651 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_failed_ops); | ||
1652 | err = register_netdev(netdev); | ||
1653 | if (err) { | ||
1654 | dev_err(&pdev->dev, "failed to register net device\n"); | ||
1655 | goto err_out_decr_ref; | ||
1656 | } | ||
1657 | pci_set_drvdata(pdev, adapter); | ||
1658 | qlcnic_create_diag_entries(adapter); | ||
1659 | return 0; | ||
1660 | } | 1756 | } |
1661 | 1757 | ||
1662 | static void qlcnic_remove(struct pci_dev *pdev) | 1758 | static void qlcnic_remove(struct pci_dev *pdev) |
@@ -1933,7 +2029,7 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) | |||
1933 | return stats; | 2029 | return stats; |
1934 | } | 2030 | } |
1935 | 2031 | ||
1936 | static irqreturn_t qlcnic_clear_legacy_intr(struct qlcnic_adapter *adapter) | 2032 | irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *adapter) |
1937 | { | 2033 | { |
1938 | u32 status; | 2034 | u32 status; |
1939 | 2035 | ||
@@ -2313,7 +2409,7 @@ wait_npar: | |||
2313 | 2409 | ||
2314 | switch (dev_state) { | 2410 | switch (dev_state) { |
2315 | case QLCNIC_DEV_READY: | 2411 | case QLCNIC_DEV_READY: |
2316 | if (!adapter->nic_ops->start_firmware(adapter)) { | 2412 | if (!qlcnic_start_firmware(adapter)) { |
2317 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2413 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2318 | adapter->fw_wait_cnt = 0; | 2414 | adapter->fw_wait_cnt = 0; |
2319 | return; | 2415 | return; |
@@ -2411,9 +2507,7 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) | |||
2411 | qlcnic_api_unlock(adapter); | 2507 | qlcnic_api_unlock(adapter); |
2412 | } | 2508 | } |
2413 | 2509 | ||
2414 | /*Transit to RESET state from READY state only */ | 2510 | void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *adapter, u32 key) |
2415 | void | ||
2416 | qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | ||
2417 | { | 2511 | { |
2418 | u32 state, xg_val = 0, gb_val = 0; | 2512 | u32 state, xg_val = 0, gb_val = 0; |
2419 | 2513 | ||
@@ -2536,7 +2630,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) | |||
2536 | goto detach; | 2630 | goto detach; |
2537 | 2631 | ||
2538 | if (adapter->need_fw_reset) | 2632 | if (adapter->need_fw_reset) |
2539 | qlcnic_dev_request_reset(adapter); | 2633 | qlcnic_dev_request_reset(adapter, 0); |
2540 | 2634 | ||
2541 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2635 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2542 | if (state == QLCNIC_DEV_NEED_RESET) { | 2636 | if (state == QLCNIC_DEV_NEED_RESET) { |
@@ -2565,7 +2659,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) | |||
2565 | 2659 | ||
2566 | adapter->flags |= QLCNIC_FW_HANG; | 2660 | adapter->flags |= QLCNIC_FW_HANG; |
2567 | 2661 | ||
2568 | qlcnic_dev_request_reset(adapter); | 2662 | qlcnic_dev_request_reset(adapter, 0); |
2569 | 2663 | ||
2570 | if (qlcnic_auto_fw_reset) | 2664 | if (qlcnic_auto_fw_reset) |
2571 | clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); | 2665 | clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); |
@@ -2677,7 +2771,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) | |||
2677 | return err; | 2771 | return err; |
2678 | 2772 | ||
2679 | qlcnic_clr_drv_state(adapter); | 2773 | qlcnic_clr_drv_state(adapter); |
2680 | qlcnic_setup_intr(adapter); | 2774 | qlcnic_setup_intr(adapter, 0); |
2681 | 2775 | ||
2682 | if (netif_running(netdev)) { | 2776 | if (netif_running(netdev)) { |
2683 | err = qlcnic_attach(adapter); | 2777 | err = qlcnic_attach(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 341d37c867ff..eeefc73af7c2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -958,3 +958,13 @@ void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | |||
958 | device_remove_bin_file(dev, &bin_attr_pm_config); | 958 | device_remove_bin_file(dev, &bin_attr_pm_config); |
959 | device_remove_bin_file(dev, &bin_attr_esw_stats); | 959 | device_remove_bin_file(dev, &bin_attr_esw_stats); |
960 | } | 960 | } |
961 | |||
962 | void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter) | ||
963 | { | ||
964 | qlcnic_create_diag_entries(adapter); | ||
965 | } | ||
966 | |||
967 | void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter) | ||
968 | { | ||
969 | qlcnic_remove_diag_entries(adapter); | ||
970 | } | ||