diff options
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 121 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ctx.c | 513 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ethtool.c | 11 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hdr.h | 70 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hw.c | 14 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 40 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 195 |
7 files changed, 890 insertions, 74 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 896d40df9a13..31a0b430a9d7 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -197,8 +197,7 @@ struct cmd_desc_type0 { | |||
197 | 197 | ||
198 | __le64 addr_buffer4; | 198 | __le64 addr_buffer4; |
199 | 199 | ||
200 | __le32 reserved2; | 200 | u8 eth_addr[ETH_ALEN]; |
201 | __le16 reserved; | ||
202 | __le16 vlan_TCI; | 201 | __le16 vlan_TCI; |
203 | 202 | ||
204 | } __attribute__ ((aligned(64))); | 203 | } __attribute__ ((aligned(64))); |
@@ -315,6 +314,8 @@ struct uni_data_desc{ | |||
315 | #define QLCNIC_BRDTYPE_P3_10G_XFP 0x0032 | 314 | #define QLCNIC_BRDTYPE_P3_10G_XFP 0x0032 |
316 | #define QLCNIC_BRDTYPE_P3_10G_TP 0x0080 | 315 | #define QLCNIC_BRDTYPE_P3_10G_TP 0x0080 |
317 | 316 | ||
317 | #define QLCNIC_MSIX_TABLE_OFFSET 0x44 | ||
318 | |||
318 | /* Flash memory map */ | 319 | /* Flash memory map */ |
319 | #define QLCNIC_BRDCFG_START 0x4000 /* board config */ | 320 | #define QLCNIC_BRDCFG_START 0x4000 /* board config */ |
320 | #define QLCNIC_BOOTLD_START 0x10000 /* bootld */ | 321 | #define QLCNIC_BOOTLD_START 0x10000 /* bootld */ |
@@ -542,7 +543,17 @@ struct qlcnic_recv_context { | |||
542 | #define QLCNIC_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c | 543 | #define QLCNIC_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c |
543 | #define QLCNIC_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d | 544 | #define QLCNIC_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d |
544 | #define QLCNIC_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e | 545 | #define QLCNIC_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e |
545 | #define QLCNIC_CDRP_CMD_MAX 0x0000001f | 546 | #define QLCNIC_CDRP_CMD_MAC_ADDRESS 0x0000001f |
547 | |||
548 | #define QLCNIC_CDRP_CMD_GET_PCI_INFO 0x00000020 | ||
549 | #define QLCNIC_CDRP_CMD_GET_NIC_INFO 0x00000021 | ||
550 | #define QLCNIC_CDRP_CMD_SET_NIC_INFO 0x00000022 | ||
551 | #define QLCNIC_CDRP_CMD_RESET_NPAR 0x00000023 | ||
552 | #define QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY 0x00000024 | ||
553 | #define QLCNIC_CDRP_CMD_TOGGLE_ESWITCH 0x00000025 | ||
554 | #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 | ||
555 | #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027 | ||
556 | #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 | ||
546 | 557 | ||
547 | #define QLCNIC_RCODE_SUCCESS 0 | 558 | #define QLCNIC_RCODE_SUCCESS 0 |
548 | #define QLCNIC_RCODE_TIMEOUT 17 | 559 | #define QLCNIC_RCODE_TIMEOUT 17 |
@@ -560,7 +571,6 @@ struct qlcnic_recv_context { | |||
560 | /* | 571 | /* |
561 | * Context state | 572 | * Context state |
562 | */ | 573 | */ |
563 | #define QLCHAL_VERSION 1 | ||
564 | 574 | ||
565 | #define QLCNIC_HOST_CTX_STATE_ACTIVE 2 | 575 | #define QLCNIC_HOST_CTX_STATE_ACTIVE 2 |
566 | 576 | ||
@@ -887,6 +897,7 @@ struct qlcnic_mac_req { | |||
887 | #define MSIX_ENTRIES_PER_ADAPTER NUM_STS_DESC_RINGS | 897 | #define MSIX_ENTRIES_PER_ADAPTER NUM_STS_DESC_RINGS |
888 | #define QLCNIC_MSIX_TBL_SPACE 8192 | 898 | #define QLCNIC_MSIX_TBL_SPACE 8192 |
889 | #define QLCNIC_PCI_REG_MSIX_TBL 0x44 | 899 | #define QLCNIC_PCI_REG_MSIX_TBL 0x44 |
900 | #define QLCNIC_MSIX_TBL_PGSIZE 4096 | ||
890 | 901 | ||
891 | #define QLCNIC_NETDEV_WEIGHT 128 | 902 | #define QLCNIC_NETDEV_WEIGHT 128 |
892 | #define QLCNIC_ADAPTER_UP_MAGIC 777 | 903 | #define QLCNIC_ADAPTER_UP_MAGIC 777 |
@@ -923,7 +934,6 @@ struct qlcnic_adapter { | |||
923 | u8 mc_enabled; | 934 | u8 mc_enabled; |
924 | u8 max_mc_count; | 935 | u8 max_mc_count; |
925 | u8 rss_supported; | 936 | u8 rss_supported; |
926 | u8 rsrvd1; | ||
927 | u8 fw_wait_cnt; | 937 | u8 fw_wait_cnt; |
928 | u8 fw_fail_cnt; | 938 | u8 fw_fail_cnt; |
929 | u8 tx_timeo_cnt; | 939 | u8 tx_timeo_cnt; |
@@ -940,6 +950,15 @@ struct qlcnic_adapter { | |||
940 | u16 link_autoneg; | 950 | u16 link_autoneg; |
941 | u16 module_type; | 951 | u16 module_type; |
942 | 952 | ||
953 | u16 op_mode; | ||
954 | u16 switch_mode; | ||
955 | u16 max_tx_ques; | ||
956 | u16 max_rx_ques; | ||
957 | u16 min_tx_bw; | ||
958 | u16 max_tx_bw; | ||
959 | u16 max_mtu; | ||
960 | |||
961 | u32 fw_hal_version; | ||
943 | u32 capabilities; | 962 | u32 capabilities; |
944 | u32 flags; | 963 | u32 flags; |
945 | u32 irq; | 964 | u32 irq; |
@@ -948,18 +967,22 @@ struct qlcnic_adapter { | |||
948 | u32 int_vec_bit; | 967 | u32 int_vec_bit; |
949 | u32 heartbit; | 968 | u32 heartbit; |
950 | 969 | ||
970 | u8 max_mac_filters; | ||
951 | u8 dev_state; | 971 | u8 dev_state; |
952 | u8 diag_test; | 972 | u8 diag_test; |
953 | u8 diag_cnt; | 973 | u8 diag_cnt; |
954 | u8 reset_ack_timeo; | 974 | u8 reset_ack_timeo; |
955 | u8 dev_init_timeo; | 975 | u8 dev_init_timeo; |
956 | u8 rsrd1; | ||
957 | u16 msg_enable; | 976 | u16 msg_enable; |
958 | 977 | ||
959 | u8 mac_addr[ETH_ALEN]; | 978 | u8 mac_addr[ETH_ALEN]; |
960 | 979 | ||
961 | u64 dev_rst_time; | 980 | u64 dev_rst_time; |
962 | 981 | ||
982 | struct qlcnic_pci_info *npars; | ||
983 | struct qlcnic_eswitch *eswitch; | ||
984 | struct qlcnic_nic_template *nic_ops; | ||
985 | |||
963 | struct qlcnic_adapter_stats stats; | 986 | struct qlcnic_adapter_stats stats; |
964 | 987 | ||
965 | struct qlcnic_recv_context recv_ctx; | 988 | struct qlcnic_recv_context recv_ctx; |
@@ -984,6 +1007,53 @@ struct qlcnic_adapter { | |||
984 | const struct firmware *fw; | 1007 | const struct firmware *fw; |
985 | }; | 1008 | }; |
986 | 1009 | ||
1010 | struct qlcnic_info { | ||
1011 | __le16 pci_func; | ||
1012 | __le16 op_mode; /* 1 = Priv, 2 = NP, 3 = NP passthru */ | ||
1013 | __le16 phys_port; | ||
1014 | __le16 switch_mode; /* 0 = disabled, 1 = int, 2 = ext */ | ||
1015 | |||
1016 | __le32 capabilities; | ||
1017 | u8 max_mac_filters; | ||
1018 | u8 reserved1; | ||
1019 | __le16 max_mtu; | ||
1020 | |||
1021 | __le16 max_tx_ques; | ||
1022 | __le16 max_rx_ques; | ||
1023 | __le16 min_tx_bw; | ||
1024 | __le16 max_tx_bw; | ||
1025 | u8 reserved2[104]; | ||
1026 | }; | ||
1027 | |||
1028 | struct qlcnic_pci_info { | ||
1029 | __le16 id; /* pci function id */ | ||
1030 | __le16 active; /* 1 = Enabled */ | ||
1031 | __le16 type; /* 1 = NIC, 2 = FCoE, 3 = iSCSI */ | ||
1032 | __le16 default_port; /* default port number */ | ||
1033 | |||
1034 | __le16 tx_min_bw; /* Multiple of 100mbpc */ | ||
1035 | __le16 tx_max_bw; | ||
1036 | __le16 reserved1[2]; | ||
1037 | |||
1038 | u8 mac[ETH_ALEN]; | ||
1039 | u8 reserved2[106]; | ||
1040 | }; | ||
1041 | |||
1042 | struct qlcnic_eswitch { | ||
1043 | u8 port; | ||
1044 | u8 active_vports; | ||
1045 | u8 active_vlans; | ||
1046 | u8 active_ucast_filters; | ||
1047 | u8 max_ucast_filters; | ||
1048 | u8 max_active_vlans; | ||
1049 | |||
1050 | u32 flags; | ||
1051 | #define QLCNIC_SWITCH_ENABLE BIT_1 | ||
1052 | #define QLCNIC_SWITCH_VLAN_FILTERING BIT_2 | ||
1053 | #define QLCNIC_SWITCH_PROMISC_MODE BIT_3 | ||
1054 | #define QLCNIC_SWITCH_PORT_MIRRORING BIT_4 | ||
1055 | }; | ||
1056 | |||
987 | int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); | 1057 | int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); |
988 | int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val); | 1058 | int qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val); |
989 | 1059 | ||
@@ -1070,13 +1140,14 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup); | |||
1070 | int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); | 1140 | int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu); |
1071 | int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); | 1141 | int qlcnic_change_mtu(struct net_device *netdev, int new_mtu); |
1072 | int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable); | 1142 | int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable); |
1073 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, int enable); | 1143 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); |
1074 | int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); | 1144 | int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); |
1075 | void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, | 1145 | void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, |
1076 | struct qlcnic_host_tx_ring *tx_ring); | 1146 | struct qlcnic_host_tx_ring *tx_ring); |
1077 | int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u64 *mac); | 1147 | int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac); |
1078 | void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter); | 1148 | void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter); |
1079 | int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter); | 1149 | int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter); |
1150 | void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); | ||
1080 | 1151 | ||
1081 | /* Functions from qlcnic_main.c */ | 1152 | /* Functions from qlcnic_main.c */ |
1082 | int qlcnic_reset_context(struct qlcnic_adapter *); | 1153 | int qlcnic_reset_context(struct qlcnic_adapter *); |
@@ -1088,6 +1159,32 @@ int qlcnic_check_loopback_buff(unsigned char *data); | |||
1088 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 1159 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
1089 | void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); | 1160 | void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); |
1090 | 1161 | ||
1162 | /* Functions from qlcnic_vf.c */ | ||
1163 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); | ||
1164 | int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); | ||
1165 | int qlcnicvf_set_ilb_mode(struct qlcnic_adapter *adapter); | ||
1166 | void qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *adapter); | ||
1167 | void qlcnicvf_set_port_mode(struct qlcnic_adapter *adapter); | ||
1168 | |||
1169 | /* Management functions */ | ||
1170 | int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); | ||
1171 | int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); | ||
1172 | int qlcnic_get_nic_info(struct qlcnic_adapter *, u8); | ||
1173 | int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); | ||
1174 | int qlcnic_get_pci_info(struct qlcnic_adapter *); | ||
1175 | int qlcnic_reset_partition(struct qlcnic_adapter *, u8); | ||
1176 | |||
1177 | /* eSwitch management functions */ | ||
1178 | int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8, | ||
1179 | struct qlcnic_eswitch *); | ||
1180 | int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8, | ||
1181 | struct qlcnic_eswitch *); | ||
1182 | int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); | ||
1183 | int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8, | ||
1184 | u8, u8, u16); | ||
1185 | int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); | ||
1186 | extern int qlcnic_config_tso; | ||
1187 | |||
1091 | /* | 1188 | /* |
1092 | * QLOGIC Board information | 1189 | * QLOGIC Board information |
1093 | */ | 1190 | */ |
@@ -1131,6 +1228,14 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring) | |||
1131 | 1228 | ||
1132 | extern const struct ethtool_ops qlcnic_ethtool_ops; | 1229 | extern const struct ethtool_ops qlcnic_ethtool_ops; |
1133 | 1230 | ||
1231 | struct qlcnic_nic_template { | ||
1232 | int (*get_mac_addr) (struct qlcnic_adapter *, u8*); | ||
1233 | int (*config_bridged_mode) (struct qlcnic_adapter *, u32); | ||
1234 | int (*config_led) (struct qlcnic_adapter *, u32, u32); | ||
1235 | int (*set_ilb_mode) (struct qlcnic_adapter *); | ||
1236 | void (*clear_ilb_mode) (struct qlcnic_adapter *); | ||
1237 | }; | ||
1238 | |||
1134 | #define QLCDB(adapter, lvl, _fmt, _args...) do { \ | 1239 | #define QLCDB(adapter, lvl, _fmt, _args...) do { \ |
1135 | if (NETIF_MSG_##lvl & adapter->msg_enable) \ | 1240 | if (NETIF_MSG_##lvl & adapter->msg_enable) \ |
1136 | printk(KERN_INFO "%s: %s: " _fmt, \ | 1241 | printk(KERN_INFO "%s: %s: " _fmt, \ |
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index c2c1f5cc16c6..1e1dc58cddca 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c | |||
@@ -88,12 +88,12 @@ qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu) | |||
88 | 88 | ||
89 | if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) { | 89 | if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) { |
90 | if (qlcnic_issue_cmd(adapter, | 90 | if (qlcnic_issue_cmd(adapter, |
91 | adapter->ahw.pci_func, | 91 | adapter->ahw.pci_func, |
92 | QLCHAL_VERSION, | 92 | adapter->fw_hal_version, |
93 | recv_ctx->context_id, | 93 | recv_ctx->context_id, |
94 | mtu, | 94 | mtu, |
95 | 0, | 95 | 0, |
96 | QLCNIC_CDRP_CMD_SET_MTU)) { | 96 | QLCNIC_CDRP_CMD_SET_MTU)) { |
97 | 97 | ||
98 | dev_err(&adapter->pdev->dev, "Failed to set mtu\n"); | 98 | dev_err(&adapter->pdev->dev, "Failed to set mtu\n"); |
99 | return -EIO; | 99 | return -EIO; |
@@ -121,7 +121,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
121 | 121 | ||
122 | int i, nrds_rings, nsds_rings; | 122 | int i, nrds_rings, nsds_rings; |
123 | size_t rq_size, rsp_size; | 123 | size_t rq_size, rsp_size; |
124 | u32 cap, reg, val; | 124 | u32 cap, reg, val, reg2; |
125 | int err; | 125 | int err; |
126 | 126 | ||
127 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | 127 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; |
@@ -197,7 +197,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
197 | phys_addr = hostrq_phys_addr; | 197 | phys_addr = hostrq_phys_addr; |
198 | err = qlcnic_issue_cmd(adapter, | 198 | err = qlcnic_issue_cmd(adapter, |
199 | adapter->ahw.pci_func, | 199 | adapter->ahw.pci_func, |
200 | QLCHAL_VERSION, | 200 | adapter->fw_hal_version, |
201 | (u32)(phys_addr >> 32), | 201 | (u32)(phys_addr >> 32), |
202 | (u32)(phys_addr & 0xffffffff), | 202 | (u32)(phys_addr & 0xffffffff), |
203 | rq_size, | 203 | rq_size, |
@@ -216,8 +216,12 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
216 | rds_ring = &recv_ctx->rds_rings[i]; | 216 | rds_ring = &recv_ctx->rds_rings[i]; |
217 | 217 | ||
218 | reg = le32_to_cpu(prsp_rds[i].host_producer_crb); | 218 | reg = le32_to_cpu(prsp_rds[i].host_producer_crb); |
219 | rds_ring->crb_rcv_producer = qlcnic_get_ioaddr(adapter, | 219 | if (adapter->fw_hal_version == QLCNIC_FW_BASE) |
220 | rds_ring->crb_rcv_producer = qlcnic_get_ioaddr(adapter, | ||
220 | QLCNIC_REG(reg - 0x200)); | 221 | QLCNIC_REG(reg - 0x200)); |
222 | else | ||
223 | rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 + | ||
224 | reg; | ||
221 | } | 225 | } |
222 | 226 | ||
223 | prsp_sds = ((struct qlcnic_cardrsp_sds_ring *) | 227 | prsp_sds = ((struct qlcnic_cardrsp_sds_ring *) |
@@ -227,12 +231,18 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
227 | sds_ring = &recv_ctx->sds_rings[i]; | 231 | sds_ring = &recv_ctx->sds_rings[i]; |
228 | 232 | ||
229 | reg = le32_to_cpu(prsp_sds[i].host_consumer_crb); | 233 | reg = le32_to_cpu(prsp_sds[i].host_consumer_crb); |
230 | sds_ring->crb_sts_consumer = qlcnic_get_ioaddr(adapter, | 234 | reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb); |
231 | QLCNIC_REG(reg - 0x200)); | ||
232 | 235 | ||
233 | reg = le32_to_cpu(prsp_sds[i].interrupt_crb); | 236 | if (adapter->fw_hal_version == QLCNIC_FW_BASE) { |
234 | sds_ring->crb_intr_mask = qlcnic_get_ioaddr(adapter, | 237 | sds_ring->crb_sts_consumer = qlcnic_get_ioaddr(adapter, |
235 | QLCNIC_REG(reg - 0x200)); | 238 | QLCNIC_REG(reg - 0x200)); |
239 | sds_ring->crb_intr_mask = qlcnic_get_ioaddr(adapter, | ||
240 | QLCNIC_REG(reg2 - 0x200)); | ||
241 | } else { | ||
242 | sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 + | ||
243 | reg; | ||
244 | sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2; | ||
245 | } | ||
236 | } | 246 | } |
237 | 247 | ||
238 | recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); | 248 | recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); |
@@ -253,7 +263,7 @@ qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter) | |||
253 | 263 | ||
254 | if (qlcnic_issue_cmd(adapter, | 264 | if (qlcnic_issue_cmd(adapter, |
255 | adapter->ahw.pci_func, | 265 | adapter->ahw.pci_func, |
256 | QLCHAL_VERSION, | 266 | adapter->fw_hal_version, |
257 | recv_ctx->context_id, | 267 | recv_ctx->context_id, |
258 | QLCNIC_DESTROY_CTX_RESET, | 268 | QLCNIC_DESTROY_CTX_RESET, |
259 | 0, | 269 | 0, |
@@ -319,7 +329,7 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | |||
319 | phys_addr = rq_phys_addr; | 329 | phys_addr = rq_phys_addr; |
320 | err = qlcnic_issue_cmd(adapter, | 330 | err = qlcnic_issue_cmd(adapter, |
321 | adapter->ahw.pci_func, | 331 | adapter->ahw.pci_func, |
322 | QLCHAL_VERSION, | 332 | adapter->fw_hal_version, |
323 | (u32)(phys_addr >> 32), | 333 | (u32)(phys_addr >> 32), |
324 | ((u32)phys_addr & 0xffffffff), | 334 | ((u32)phys_addr & 0xffffffff), |
325 | rq_size, | 335 | rq_size, |
@@ -327,8 +337,12 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter) | |||
327 | 337 | ||
328 | if (err == QLCNIC_RCODE_SUCCESS) { | 338 | if (err == QLCNIC_RCODE_SUCCESS) { |
329 | temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); | 339 | temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); |
330 | tx_ring->crb_cmd_producer = qlcnic_get_ioaddr(adapter, | 340 | if (adapter->fw_hal_version == QLCNIC_FW_BASE) |
341 | tx_ring->crb_cmd_producer = qlcnic_get_ioaddr(adapter, | ||
331 | QLCNIC_REG(temp - 0x200)); | 342 | QLCNIC_REG(temp - 0x200)); |
343 | else | ||
344 | tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 + | ||
345 | temp; | ||
332 | 346 | ||
333 | adapter->tx_context_id = | 347 | adapter->tx_context_id = |
334 | le16_to_cpu(prsp->context_id); | 348 | le16_to_cpu(prsp->context_id); |
@@ -351,7 +365,7 @@ qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter) | |||
351 | { | 365 | { |
352 | if (qlcnic_issue_cmd(adapter, | 366 | if (qlcnic_issue_cmd(adapter, |
353 | adapter->ahw.pci_func, | 367 | adapter->ahw.pci_func, |
354 | QLCHAL_VERSION, | 368 | adapter->fw_hal_version, |
355 | adapter->tx_context_id, | 369 | adapter->tx_context_id, |
356 | QLCNIC_DESTROY_CTX_RESET, | 370 | QLCNIC_DESTROY_CTX_RESET, |
357 | 0, | 371 | 0, |
@@ -368,7 +382,7 @@ qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val) | |||
368 | 382 | ||
369 | if (qlcnic_issue_cmd(adapter, | 383 | if (qlcnic_issue_cmd(adapter, |
370 | adapter->ahw.pci_func, | 384 | adapter->ahw.pci_func, |
371 | QLCHAL_VERSION, | 385 | adapter->fw_hal_version, |
372 | reg, | 386 | reg, |
373 | 0, | 387 | 0, |
374 | 0, | 388 | 0, |
@@ -385,7 +399,7 @@ qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val) | |||
385 | { | 399 | { |
386 | return qlcnic_issue_cmd(adapter, | 400 | return qlcnic_issue_cmd(adapter, |
387 | adapter->ahw.pci_func, | 401 | adapter->ahw.pci_func, |
388 | QLCHAL_VERSION, | 402 | adapter->fw_hal_version, |
389 | reg, | 403 | reg, |
390 | val, | 404 | val, |
391 | 0, | 405 | 0, |
@@ -533,3 +547,464 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) | |||
533 | } | 547 | } |
534 | } | 548 | } |
535 | 549 | ||
550 | /* Set MAC address of a NIC partition */ | ||
551 | int qlcnic_set_mac_address(struct qlcnic_adapter *adapter, u8* mac) | ||
552 | { | ||
553 | int err = 0; | ||
554 | u32 arg1, arg2, arg3; | ||
555 | |||
556 | arg1 = adapter->ahw.pci_func | BIT_9; | ||
557 | arg2 = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24); | ||
558 | arg3 = mac[4] | (mac[5] << 16); | ||
559 | |||
560 | err = qlcnic_issue_cmd(adapter, | ||
561 | adapter->ahw.pci_func, | ||
562 | adapter->fw_hal_version, | ||
563 | arg1, | ||
564 | arg2, | ||
565 | arg3, | ||
566 | QLCNIC_CDRP_CMD_MAC_ADDRESS); | ||
567 | |||
568 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
569 | dev_err(&adapter->pdev->dev, | ||
570 | "Failed to set mac address%d\n", err); | ||
571 | err = -EIO; | ||
572 | } | ||
573 | |||
574 | return err; | ||
575 | } | ||
576 | |||
577 | /* Get MAC address of a NIC partition */ | ||
578 | int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) | ||
579 | { | ||
580 | int err; | ||
581 | u32 arg1; | ||
582 | |||
583 | arg1 = adapter->ahw.pci_func | BIT_8; | ||
584 | err = qlcnic_issue_cmd(adapter, | ||
585 | adapter->ahw.pci_func, | ||
586 | adapter->fw_hal_version, | ||
587 | arg1, | ||
588 | 0, | ||
589 | 0, | ||
590 | QLCNIC_CDRP_CMD_MAC_ADDRESS); | ||
591 | |||
592 | if (err == QLCNIC_RCODE_SUCCESS) { | ||
593 | qlcnic_fetch_mac(adapter, QLCNIC_ARG1_CRB_OFFSET, | ||
594 | QLCNIC_ARG2_CRB_OFFSET, 0, mac); | ||
595 | dev_info(&adapter->pdev->dev, "MAC address: %pM\n", mac); | ||
596 | } else { | ||
597 | dev_err(&adapter->pdev->dev, | ||
598 | "Failed to get mac address%d\n", err); | ||
599 | err = -EIO; | ||
600 | } | ||
601 | |||
602 | return err; | ||
603 | } | ||
604 | |||
605 | /* Get info of a NIC partition */ | ||
606 | int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id) | ||
607 | { | ||
608 | int err; | ||
609 | dma_addr_t nic_dma_t; | ||
610 | struct qlcnic_info *nic_info; | ||
611 | void *nic_info_addr; | ||
612 | size_t nic_size = sizeof(struct qlcnic_info); | ||
613 | |||
614 | nic_info_addr = pci_alloc_consistent(adapter->pdev, | ||
615 | nic_size, &nic_dma_t); | ||
616 | if (!nic_info_addr) | ||
617 | return -ENOMEM; | ||
618 | memset(nic_info_addr, 0, nic_size); | ||
619 | |||
620 | nic_info = (struct qlcnic_info *) nic_info_addr; | ||
621 | err = qlcnic_issue_cmd(adapter, | ||
622 | adapter->ahw.pci_func, | ||
623 | adapter->fw_hal_version, | ||
624 | MSD(nic_dma_t), | ||
625 | LSD(nic_dma_t), | ||
626 | (func_id << 16 | nic_size), | ||
627 | QLCNIC_CDRP_CMD_GET_NIC_INFO); | ||
628 | |||
629 | if (err == QLCNIC_RCODE_SUCCESS) { | ||
630 | adapter->physical_port = le16_to_cpu(nic_info->phys_port); | ||
631 | adapter->switch_mode = le16_to_cpu(nic_info->switch_mode); | ||
632 | adapter->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques); | ||
633 | adapter->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); | ||
634 | adapter->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw); | ||
635 | adapter->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw); | ||
636 | adapter->max_mtu = le16_to_cpu(nic_info->max_mtu); | ||
637 | adapter->capabilities = le32_to_cpu(nic_info->capabilities); | ||
638 | adapter->max_mac_filters = nic_info->max_mac_filters; | ||
639 | |||
640 | dev_info(&adapter->pdev->dev, | ||
641 | "phy port: %d switch_mode: %d,\n" | ||
642 | "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n" | ||
643 | "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n", | ||
644 | adapter->physical_port, adapter->switch_mode, | ||
645 | adapter->max_tx_ques, adapter->max_rx_ques, | ||
646 | adapter->min_tx_bw, adapter->max_tx_bw, | ||
647 | adapter->max_mtu, adapter->capabilities); | ||
648 | } else { | ||
649 | dev_err(&adapter->pdev->dev, | ||
650 | "Failed to get nic info%d\n", err); | ||
651 | err = -EIO; | ||
652 | } | ||
653 | |||
654 | pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t); | ||
655 | return err; | ||
656 | } | ||
657 | |||
658 | /* Configure a NIC partition */ | ||
659 | int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic) | ||
660 | { | ||
661 | int err = -EIO; | ||
662 | u32 func_state; | ||
663 | dma_addr_t nic_dma_t; | ||
664 | void *nic_info_addr; | ||
665 | struct qlcnic_info *nic_info; | ||
666 | size_t nic_size = sizeof(struct qlcnic_info); | ||
667 | |||
668 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
669 | return err; | ||
670 | |||
671 | if (qlcnic_api_lock(adapter)) | ||
672 | return err; | ||
673 | |||
674 | func_state = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
675 | if (QLC_DEV_CHECK_ACTIVE(func_state, nic->pci_func)) { | ||
676 | qlcnic_api_unlock(adapter); | ||
677 | return err; | ||
678 | } | ||
679 | |||
680 | qlcnic_api_unlock(adapter); | ||
681 | |||
682 | nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size, | ||
683 | &nic_dma_t); | ||
684 | if (!nic_info_addr) | ||
685 | return -ENOMEM; | ||
686 | |||
687 | memset(nic_info_addr, 0, nic_size); | ||
688 | nic_info = (struct qlcnic_info *)nic_info_addr; | ||
689 | |||
690 | nic_info->pci_func = cpu_to_le16(nic->pci_func); | ||
691 | nic_info->op_mode = cpu_to_le16(nic->op_mode); | ||
692 | nic_info->phys_port = cpu_to_le16(nic->phys_port); | ||
693 | nic_info->switch_mode = cpu_to_le16(nic->switch_mode); | ||
694 | nic_info->capabilities = cpu_to_le32(nic->capabilities); | ||
695 | nic_info->max_mac_filters = nic->max_mac_filters; | ||
696 | nic_info->max_tx_ques = cpu_to_le16(nic->max_tx_ques); | ||
697 | nic_info->max_rx_ques = cpu_to_le16(nic->max_rx_ques); | ||
698 | nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw); | ||
699 | nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw); | ||
700 | |||
701 | err = qlcnic_issue_cmd(adapter, | ||
702 | adapter->ahw.pci_func, | ||
703 | adapter->fw_hal_version, | ||
704 | MSD(nic_dma_t), | ||
705 | LSD(nic_dma_t), | ||
706 | nic_size, | ||
707 | QLCNIC_CDRP_CMD_SET_NIC_INFO); | ||
708 | |||
709 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
710 | dev_err(&adapter->pdev->dev, | ||
711 | "Failed to set nic info%d\n", err); | ||
712 | err = -EIO; | ||
713 | } | ||
714 | |||
715 | pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t); | ||
716 | return err; | ||
717 | } | ||
718 | |||
719 | /* Get PCI Info of a partition */ | ||
720 | int qlcnic_get_pci_info(struct qlcnic_adapter *adapter) | ||
721 | { | ||
722 | int err = 0, i; | ||
723 | dma_addr_t pci_info_dma_t; | ||
724 | struct qlcnic_pci_info *npar; | ||
725 | void *pci_info_addr; | ||
726 | size_t npar_size = sizeof(struct qlcnic_pci_info); | ||
727 | size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC; | ||
728 | |||
729 | pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size, | ||
730 | &pci_info_dma_t); | ||
731 | if (!pci_info_addr) | ||
732 | return -ENOMEM; | ||
733 | memset(pci_info_addr, 0, pci_size); | ||
734 | |||
735 | if (!adapter->npars) | ||
736 | adapter->npars = kzalloc(pci_size, GFP_KERNEL); | ||
737 | if (!adapter->npars) { | ||
738 | err = -ENOMEM; | ||
739 | goto err_npar; | ||
740 | } | ||
741 | |||
742 | if (!adapter->eswitch) | ||
743 | adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * | ||
744 | QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); | ||
745 | if (!adapter->eswitch) { | ||
746 | err = -ENOMEM; | ||
747 | goto err_eswitch; | ||
748 | } | ||
749 | |||
750 | npar = (struct qlcnic_pci_info *) pci_info_addr; | ||
751 | err = qlcnic_issue_cmd(adapter, | ||
752 | adapter->ahw.pci_func, | ||
753 | adapter->fw_hal_version, | ||
754 | MSD(pci_info_dma_t), | ||
755 | LSD(pci_info_dma_t), | ||
756 | pci_size, | ||
757 | QLCNIC_CDRP_CMD_GET_PCI_INFO); | ||
758 | |||
759 | if (err == QLCNIC_RCODE_SUCCESS) { | ||
760 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++) { | ||
761 | adapter->npars[i].id = le32_to_cpu(npar->id); | ||
762 | adapter->npars[i].active = le32_to_cpu(npar->active); | ||
763 | adapter->npars[i].type = le32_to_cpu(npar->type); | ||
764 | adapter->npars[i].default_port = | ||
765 | le32_to_cpu(npar->default_port); | ||
766 | adapter->npars[i].tx_min_bw = | ||
767 | le32_to_cpu(npar->tx_min_bw); | ||
768 | adapter->npars[i].tx_max_bw = | ||
769 | le32_to_cpu(npar->tx_max_bw); | ||
770 | memcpy(adapter->npars[i].mac, npar->mac, ETH_ALEN); | ||
771 | } | ||
772 | } else { | ||
773 | dev_err(&adapter->pdev->dev, | ||
774 | "Failed to get PCI Info%d\n", err); | ||
775 | kfree(adapter->npars); | ||
776 | err = -EIO; | ||
777 | } | ||
778 | goto err_npar; | ||
779 | |||
780 | err_eswitch: | ||
781 | kfree(adapter->npars); | ||
782 | adapter->npars = NULL; | ||
783 | |||
784 | err_npar: | ||
785 | pci_free_consistent(adapter->pdev, pci_size, pci_info_addr, | ||
786 | pci_info_dma_t); | ||
787 | return err; | ||
788 | } | ||
789 | |||
790 | /* Reset a NIC partition */ | ||
791 | |||
792 | int qlcnic_reset_partition(struct qlcnic_adapter *adapter, u8 func_no) | ||
793 | { | ||
794 | int err = -EIO; | ||
795 | |||
796 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
797 | return err; | ||
798 | |||
799 | err = qlcnic_issue_cmd(adapter, | ||
800 | adapter->ahw.pci_func, | ||
801 | adapter->fw_hal_version, | ||
802 | func_no, | ||
803 | 0, | ||
804 | 0, | ||
805 | QLCNIC_CDRP_CMD_RESET_NPAR); | ||
806 | |||
807 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
808 | dev_err(&adapter->pdev->dev, | ||
809 | "Failed to issue reset partition%d\n", err); | ||
810 | err = -EIO; | ||
811 | } | ||
812 | |||
813 | return err; | ||
814 | } | ||
815 | |||
816 | /* Get eSwitch Capabilities */ | ||
817 | int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, | ||
818 | struct qlcnic_eswitch *eswitch) | ||
819 | { | ||
820 | int err = -EIO; | ||
821 | u32 arg1, arg2; | ||
822 | |||
823 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) | ||
824 | return err; | ||
825 | |||
826 | err = qlcnic_issue_cmd(adapter, | ||
827 | adapter->ahw.pci_func, | ||
828 | adapter->fw_hal_version, | ||
829 | port, | ||
830 | 0, | ||
831 | 0, | ||
832 | QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY); | ||
833 | |||
834 | if (err == QLCNIC_RCODE_SUCCESS) { | ||
835 | arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); | ||
836 | arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); | ||
837 | |||
838 | eswitch->port = arg1 & 0xf; | ||
839 | eswitch->active_vports = LSB(arg2); | ||
840 | eswitch->max_ucast_filters = MSB(arg2); | ||
841 | eswitch->max_active_vlans = LSB(MSW(arg2)); | ||
842 | if (arg1 & BIT_6) | ||
843 | eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; | ||
844 | if (arg1 & BIT_7) | ||
845 | eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE; | ||
846 | if (arg1 & BIT_8) | ||
847 | eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; | ||
848 | } else { | ||
849 | dev_err(&adapter->pdev->dev, | ||
850 | "Failed to get eswitch capabilities%d\n", err); | ||
851 | } | ||
852 | |||
853 | return err; | ||
854 | } | ||
855 | |||
856 | /* Get current status of eswitch */ | ||
857 | int qlcnic_get_eswitch_status(struct qlcnic_adapter *adapter, u8 port, | ||
858 | struct qlcnic_eswitch *eswitch) | ||
859 | { | ||
860 | int err = -EIO; | ||
861 | u32 arg1, arg2; | ||
862 | |||
863 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
864 | return err; | ||
865 | |||
866 | err = qlcnic_issue_cmd(adapter, | ||
867 | adapter->ahw.pci_func, | ||
868 | adapter->fw_hal_version, | ||
869 | port, | ||
870 | 0, | ||
871 | 0, | ||
872 | QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS); | ||
873 | |||
874 | if (err == QLCNIC_RCODE_SUCCESS) { | ||
875 | arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); | ||
876 | arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); | ||
877 | |||
878 | eswitch->port = arg1 & 0xf; | ||
879 | eswitch->active_vports = LSB(arg2); | ||
880 | eswitch->active_ucast_filters = MSB(arg2); | ||
881 | eswitch->active_vlans = LSB(MSW(arg2)); | ||
882 | if (arg1 & BIT_6) | ||
883 | eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; | ||
884 | if (arg1 & BIT_8) | ||
885 | eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; | ||
886 | |||
887 | } else { | ||
888 | dev_err(&adapter->pdev->dev, | ||
889 | "Failed to get eswitch status%d\n", err); | ||
890 | } | ||
891 | |||
892 | return err; | ||
893 | } | ||
894 | |||
895 | /* Enable/Disable eSwitch */ | ||
896 | int qlcnic_toggle_eswitch(struct qlcnic_adapter *adapter, u8 id, u8 enable) | ||
897 | { | ||
898 | int err = -EIO; | ||
899 | u32 arg1, arg2; | ||
900 | struct qlcnic_eswitch *eswitch; | ||
901 | |||
902 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
903 | return err; | ||
904 | |||
905 | eswitch = &adapter->eswitch[id]; | ||
906 | if (!eswitch) | ||
907 | return err; | ||
908 | |||
909 | arg1 = eswitch->port | (enable ? BIT_4 : 0); | ||
910 | arg2 = eswitch->active_vports | (eswitch->max_ucast_filters << 8) | | ||
911 | (eswitch->max_active_vlans << 16); | ||
912 | err = qlcnic_issue_cmd(adapter, | ||
913 | adapter->ahw.pci_func, | ||
914 | adapter->fw_hal_version, | ||
915 | arg1, | ||
916 | arg2, | ||
917 | 0, | ||
918 | QLCNIC_CDRP_CMD_TOGGLE_ESWITCH); | ||
919 | |||
920 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
921 | dev_err(&adapter->pdev->dev, | ||
922 | "Failed to enable eswitch%d\n", eswitch->port); | ||
923 | eswitch->flags &= ~QLCNIC_SWITCH_ENABLE; | ||
924 | err = -EIO; | ||
925 | } else { | ||
926 | eswitch->flags |= QLCNIC_SWITCH_ENABLE; | ||
927 | dev_info(&adapter->pdev->dev, | ||
928 | "Enabled eSwitch for port %d\n", eswitch->port); | ||
929 | } | ||
930 | |||
931 | return err; | ||
932 | } | ||
933 | |||
934 | /* Configure eSwitch for port mirroring */ | ||
935 | int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, | ||
936 | u8 enable_mirroring, u8 pci_func) | ||
937 | { | ||
938 | int err = -EIO; | ||
939 | u32 arg1; | ||
940 | |||
941 | if (adapter->op_mode != QLCNIC_MGMT_FUNC || | ||
942 | !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) | ||
943 | return err; | ||
944 | |||
945 | arg1 = id | (enable_mirroring ? BIT_4 : 0); | ||
946 | arg1 |= pci_func << 8; | ||
947 | |||
948 | err = qlcnic_issue_cmd(adapter, | ||
949 | adapter->ahw.pci_func, | ||
950 | adapter->fw_hal_version, | ||
951 | arg1, | ||
952 | 0, | ||
953 | 0, | ||
954 | QLCNIC_CDRP_CMD_SET_PORTMIRRORING); | ||
955 | |||
956 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
957 | dev_err(&adapter->pdev->dev, | ||
958 | "Failed to configure port mirroring%d on eswitch:%d\n", | ||
959 | pci_func, id); | ||
960 | } else { | ||
961 | dev_info(&adapter->pdev->dev, | ||
962 | "Configured eSwitch %d for port mirroring:%d\n", | ||
963 | id, pci_func); | ||
964 | } | ||
965 | |||
966 | return err; | ||
967 | } | ||
968 | |||
969 | /* Configure eSwitch port */ | ||
970 | int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id, | ||
971 | int vlan_tagging, u8 discard_tagged, u8 promsc_mode, | ||
972 | u8 mac_learn, u8 pci_func, u16 vlan_id) | ||
973 | { | ||
974 | int err = -EIO; | ||
975 | u32 arg1; | ||
976 | struct qlcnic_eswitch *eswitch; | ||
977 | |||
978 | if (adapter->op_mode != QLCNIC_MGMT_FUNC) | ||
979 | return err; | ||
980 | |||
981 | eswitch = &adapter->eswitch[id]; | ||
982 | if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE)) | ||
983 | return err; | ||
984 | |||
985 | arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0); | ||
986 | arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0); | ||
987 | arg1 |= pci_func << 8; | ||
988 | if (vlan_tagging) | ||
989 | arg1 |= BIT_5 | (vlan_id << 16); | ||
990 | |||
991 | err = qlcnic_issue_cmd(adapter, | ||
992 | adapter->ahw.pci_func, | ||
993 | adapter->fw_hal_version, | ||
994 | arg1, | ||
995 | 0, | ||
996 | 0, | ||
997 | QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH); | ||
998 | |||
999 | if (err != QLCNIC_RCODE_SUCCESS) { | ||
1000 | dev_err(&adapter->pdev->dev, | ||
1001 | "Failed to configure eswitch port%d\n", eswitch->port); | ||
1002 | eswitch->flags |= QLCNIC_SWITCH_ENABLE; | ||
1003 | } else { | ||
1004 | eswitch->flags &= ~QLCNIC_SWITCH_ENABLE; | ||
1005 | dev_info(&adapter->pdev->dev, | ||
1006 | "Configured eSwitch for port %d\n", eswitch->port); | ||
1007 | } | ||
1008 | |||
1009 | return err; | ||
1010 | } | ||
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 3bd514ec7e8f..3e4822ad5a80 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c | |||
@@ -683,13 +683,13 @@ static int qlcnic_loopback_test(struct net_device *netdev) | |||
683 | if (ret) | 683 | if (ret) |
684 | goto clear_it; | 684 | goto clear_it; |
685 | 685 | ||
686 | ret = qlcnic_set_ilb_mode(adapter); | 686 | ret = adapter->nic_ops->set_ilb_mode(adapter); |
687 | if (ret) | 687 | if (ret) |
688 | goto done; | 688 | goto done; |
689 | 689 | ||
690 | ret = qlcnic_do_ilb_test(adapter); | 690 | ret = qlcnic_do_ilb_test(adapter); |
691 | 691 | ||
692 | qlcnic_clear_ilb_mode(adapter); | 692 | adapter->nic_ops->clear_ilb_mode(adapter); |
693 | 693 | ||
694 | done: | 694 | done: |
695 | qlcnic_diag_free_res(netdev, max_sds_rings); | 695 | qlcnic_diag_free_res(netdev, max_sds_rings); |
@@ -715,7 +715,8 @@ static int qlcnic_irq_test(struct net_device *netdev) | |||
715 | 715 | ||
716 | adapter->diag_cnt = 0; | 716 | adapter->diag_cnt = 0; |
717 | ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, | 717 | ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, |
718 | QLCHAL_VERSION, adapter->portnum, 0, 0, 0x00000011); | 718 | adapter->fw_hal_version, adapter->portnum, |
719 | 0, 0, 0x00000011); | ||
719 | if (ret) | 720 | if (ret) |
720 | goto done; | 721 | goto done; |
721 | 722 | ||
@@ -834,7 +835,7 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val) | |||
834 | struct qlcnic_adapter *adapter = netdev_priv(dev); | 835 | struct qlcnic_adapter *adapter = netdev_priv(dev); |
835 | int ret; | 836 | int ret; |
836 | 837 | ||
837 | ret = qlcnic_config_led(adapter, 1, 0xf); | 838 | ret = adapter->nic_ops->config_led(adapter, 1, 0xf); |
838 | if (ret) { | 839 | if (ret) { |
839 | dev_err(&adapter->pdev->dev, | 840 | dev_err(&adapter->pdev->dev, |
840 | "Failed to set LED blink state.\n"); | 841 | "Failed to set LED blink state.\n"); |
@@ -843,7 +844,7 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val) | |||
843 | 844 | ||
844 | msleep_interruptible(val * 1000); | 845 | msleep_interruptible(val * 1000); |
845 | 846 | ||
846 | ret = qlcnic_config_led(adapter, 0, 0xf); | 847 | ret = adapter->nic_ops->config_led(adapter, 0, 0xf); |
847 | if (ret) { | 848 | if (ret) { |
848 | dev_err(&adapter->pdev->dev, | 849 | dev_err(&adapter->pdev->dev, |
849 | "Failed to reset LED blink state.\n"); | 850 | "Failed to reset LED blink state.\n"); |
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index ad9d167723c4..1bcfb121a895 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h | |||
@@ -208,6 +208,39 @@ enum { | |||
208 | QLCNIC_HW_PX_MAP_CRB_PGR0 | 208 | QLCNIC_HW_PX_MAP_CRB_PGR0 |
209 | }; | 209 | }; |
210 | 210 | ||
211 | #define BIT_0 0x1 | ||
212 | #define BIT_1 0x2 | ||
213 | #define BIT_2 0x4 | ||
214 | #define BIT_3 0x8 | ||
215 | #define BIT_4 0x10 | ||
216 | #define BIT_5 0x20 | ||
217 | #define BIT_6 0x40 | ||
218 | #define BIT_7 0x80 | ||
219 | #define BIT_8 0x100 | ||
220 | #define BIT_9 0x200 | ||
221 | #define BIT_10 0x400 | ||
222 | #define BIT_11 0x800 | ||
223 | #define BIT_12 0x1000 | ||
224 | #define BIT_13 0x2000 | ||
225 | #define BIT_14 0x4000 | ||
226 | #define BIT_15 0x8000 | ||
227 | #define BIT_16 0x10000 | ||
228 | #define BIT_17 0x20000 | ||
229 | #define BIT_18 0x40000 | ||
230 | #define BIT_19 0x80000 | ||
231 | #define BIT_20 0x100000 | ||
232 | #define BIT_21 0x200000 | ||
233 | #define BIT_22 0x400000 | ||
234 | #define BIT_23 0x800000 | ||
235 | #define BIT_24 0x1000000 | ||
236 | #define BIT_25 0x2000000 | ||
237 | #define BIT_26 0x4000000 | ||
238 | #define BIT_27 0x8000000 | ||
239 | #define BIT_28 0x10000000 | ||
240 | #define BIT_29 0x20000000 | ||
241 | #define BIT_30 0x40000000 | ||
242 | #define BIT_31 0x80000000 | ||
243 | |||
211 | /* This field defines CRB adr [31:20] of the agents */ | 244 | /* This field defines CRB adr [31:20] of the agents */ |
212 | 245 | ||
213 | #define QLCNIC_HW_CRB_HUB_AGT_ADR_MN \ | 246 | #define QLCNIC_HW_CRB_HUB_AGT_ADR_MN \ |
@@ -684,12 +717,20 @@ enum { | |||
684 | #define QLCNIC_DEV_FAILED 0x6 | 717 | #define QLCNIC_DEV_FAILED 0x6 |
685 | #define QLCNIC_DEV_QUISCENT 0x7 | 718 | #define QLCNIC_DEV_QUISCENT 0x7 |
686 | 719 | ||
720 | #define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) | ||
687 | #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) | 721 | #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) |
688 | #define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4))) | 722 | #define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4))) |
689 | #define QLC_DEV_SET_RST_RDY(VAL, FN) ((VAL) |= (1 << (FN * 4))) | 723 | #define QLC_DEV_SET_RST_RDY(VAL, FN) ((VAL) |= (1 << (FN * 4))) |
690 | #define QLC_DEV_SET_QSCNT_RDY(VAL, FN) ((VAL) |= (2 << (FN * 4))) | 724 | #define QLC_DEV_SET_QSCNT_RDY(VAL, FN) ((VAL) |= (2 << (FN * 4))) |
691 | #define QLC_DEV_CLR_RST_QSCNT(VAL, FN) ((VAL) &= ~(3 << (FN * 4))) | 725 | #define QLC_DEV_CLR_RST_QSCNT(VAL, FN) ((VAL) &= ~(3 << (FN * 4))) |
692 | 726 | ||
727 | #define QLC_DEV_GET_DRV(VAL, FN) (0xf & ((VAL) >> (FN * 4))) | ||
728 | #define QLC_DEV_SET_DRV(VAL, FN) ((VAL) << (FN * 4)) | ||
729 | |||
730 | #define QLCNIC_TYPE_NIC 1 | ||
731 | #define QLCNIC_TYPE_FCOE 2 | ||
732 | #define QLCNIC_TYPE_ISCSI 3 | ||
733 | |||
693 | #define QLCNIC_RCODE_DRIVER_INFO 0x20000000 | 734 | #define QLCNIC_RCODE_DRIVER_INFO 0x20000000 |
694 | #define QLCNIC_RCODE_DRIVER_CAN_RELOAD 0x40000000 | 735 | #define QLCNIC_RCODE_DRIVER_CAN_RELOAD 0x40000000 |
695 | #define QLCNIC_RCODE_FATAL_ERROR 0x80000000 | 736 | #define QLCNIC_RCODE_FATAL_ERROR 0x80000000 |
@@ -721,6 +762,35 @@ struct qlcnic_legacy_intr_set { | |||
721 | u32 pci_int_reg; | 762 | u32 pci_int_reg; |
722 | }; | 763 | }; |
723 | 764 | ||
765 | #define QLCNIC_FW_API 0x1b216c | ||
766 | #define QLCNIC_DRV_OP_MODE 0x1b2170 | ||
767 | #define QLCNIC_MSIX_BASE 0x132110 | ||
768 | #define QLCNIC_MAX_PCI_FUNC 8 | ||
769 | |||
770 | /* PCI function operational mode */ | ||
771 | enum { | ||
772 | QLCNIC_MGMT_FUNC = 0, | ||
773 | QLCNIC_PRIV_FUNC = 1, | ||
774 | QLCNIC_NON_PRIV_FUNC = 2 | ||
775 | }; | ||
776 | |||
777 | /* FW HAL api version */ | ||
778 | enum { | ||
779 | QLCNIC_FW_BASE = 1, | ||
780 | QLCNIC_FW_NPAR = 2 | ||
781 | }; | ||
782 | |||
783 | #define QLC_DEV_DRV_DEFAULT 0x11111111 | ||
784 | |||
785 | #define LSB(x) ((uint8_t)(x)) | ||
786 | #define MSB(x) ((uint8_t)((uint16_t)(x) >> 8)) | ||
787 | |||
788 | #define LSW(x) ((uint16_t)((uint32_t)(x))) | ||
789 | #define MSW(x) ((uint16_t)((uint32_t)(x) >> 16)) | ||
790 | |||
791 | #define LSD(x) ((uint32_t)((uint64_t)(x))) | ||
792 | #define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) | ||
793 | |||
724 | #define QLCNIC_LEGACY_INTR_CONFIG \ | 794 | #define QLCNIC_LEGACY_INTR_CONFIG \ |
725 | { \ | 795 | { \ |
726 | { \ | 796 | { \ |
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 0c2e1f08f459..f776956d2d6c 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -538,7 +538,7 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) | |||
538 | return rv; | 538 | return rv; |
539 | } | 539 | } |
540 | 540 | ||
541 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, int enable) | 541 | int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) |
542 | { | 542 | { |
543 | struct qlcnic_nic_req req; | 543 | struct qlcnic_nic_req req; |
544 | u64 word; | 544 | u64 word; |
@@ -704,21 +704,15 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) | |||
704 | return rc; | 704 | return rc; |
705 | } | 705 | } |
706 | 706 | ||
707 | int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u64 *mac) | 707 | int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac) |
708 | { | 708 | { |
709 | u32 crbaddr, mac_hi, mac_lo; | 709 | u32 crbaddr; |
710 | int pci_func = adapter->ahw.pci_func; | 710 | int pci_func = adapter->ahw.pci_func; |
711 | 711 | ||
712 | crbaddr = CRB_MAC_BLOCK_START + | 712 | crbaddr = CRB_MAC_BLOCK_START + |
713 | (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); | 713 | (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); |
714 | 714 | ||
715 | mac_lo = QLCRD32(adapter, crbaddr); | 715 | qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac); |
716 | mac_hi = QLCRD32(adapter, crbaddr+4); | ||
717 | |||
718 | if (pci_func & 1) | ||
719 | *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16)); | ||
720 | else | ||
721 | *mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32)); | ||
722 | 716 | ||
723 | return 0; | 717 | return 0; |
724 | } | 718 | } |
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 71a4e664ad76..635c99022f06 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -520,17 +520,16 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) { | |||
520 | int timeo; | 520 | int timeo; |
521 | u32 val; | 521 | u32 val; |
522 | 522 | ||
523 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_PARTITION_INFO); | 523 | if (adapter->fw_hal_version == QLCNIC_FW_BASE) { |
524 | val = (val >> (adapter->portnum * 4)) & 0xf; | 524 | val = QLCRD32(adapter, QLCNIC_CRB_DEV_PARTITION_INFO); |
525 | 525 | val = QLC_DEV_GET_DRV(val, adapter->portnum); | |
526 | if ((val & 0x3) != 1) { | 526 | if ((val & 0x3) != QLCNIC_TYPE_NIC) { |
527 | dev_err(&adapter->pdev->dev, "Not an Ethernet NIC func=%u\n", | 527 | dev_err(&adapter->pdev->dev, |
528 | val); | 528 | "Not an Ethernet NIC func=%u\n", val); |
529 | return -EIO; | 529 | return -EIO; |
530 | } | ||
531 | adapter->physical_port = (val >> 2); | ||
530 | } | 532 | } |
531 | |||
532 | adapter->physical_port = (val >> 2); | ||
533 | |||
534 | if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo)) | 533 | if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo)) |
535 | timeo = 30; | 534 | timeo = 30; |
536 | 535 | ||
@@ -1701,3 +1700,24 @@ qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring) | |||
1701 | sds_ring->consumer = consumer; | 1700 | sds_ring->consumer = consumer; |
1702 | writel(consumer, sds_ring->crb_sts_consumer); | 1701 | writel(consumer, sds_ring->crb_sts_consumer); |
1703 | } | 1702 | } |
1703 | |||
1704 | void | ||
1705 | qlcnic_fetch_mac(struct qlcnic_adapter *adapter, u32 off1, u32 off2, | ||
1706 | u8 alt_mac, u8 *mac) | ||
1707 | { | ||
1708 | u32 mac_low, mac_high; | ||
1709 | int i; | ||
1710 | |||
1711 | mac_low = QLCRD32(adapter, off1); | ||
1712 | mac_high = QLCRD32(adapter, off2); | ||
1713 | |||
1714 | if (alt_mac) { | ||
1715 | mac_low |= (mac_low >> 16) | (mac_high << 16); | ||
1716 | mac_high >>= 16; | ||
1717 | } | ||
1718 | |||
1719 | for (i = 0; i < 2; i++) | ||
1720 | mac[i] = (u8)(mac_high >> ((1 - i) * 8)); | ||
1721 | for (i = 2; i < 6; i++) | ||
1722 | mac[i] = (u8)(mac_low >> ((5 - i) * 8)); | ||
1723 | } | ||
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 23ea9caa5261..1e5e66facabd 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -65,6 +65,10 @@ static int load_fw_file; | |||
65 | module_param(load_fw_file, int, 0644); | 65 | module_param(load_fw_file, int, 0644); |
66 | MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); | 66 | MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); |
67 | 67 | ||
68 | static int qlcnic_config_npars; | ||
69 | module_param(qlcnic_config_npars, int, 0644); | ||
70 | MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled"); | ||
71 | |||
68 | static int __devinit qlcnic_probe(struct pci_dev *pdev, | 72 | static int __devinit qlcnic_probe(struct pci_dev *pdev, |
69 | const struct pci_device_id *ent); | 73 | const struct pci_device_id *ent); |
70 | static void __devexit qlcnic_remove(struct pci_dev *pdev); | 74 | static void __devexit qlcnic_remove(struct pci_dev *pdev); |
@@ -307,19 +311,14 @@ static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count) | |||
307 | static int | 311 | static int |
308 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | 312 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) |
309 | { | 313 | { |
310 | int i; | 314 | u8 mac_addr[ETH_ALEN]; |
311 | unsigned char *p; | ||
312 | u64 mac_addr; | ||
313 | struct net_device *netdev = adapter->netdev; | 315 | struct net_device *netdev = adapter->netdev; |
314 | struct pci_dev *pdev = adapter->pdev; | 316 | struct pci_dev *pdev = adapter->pdev; |
315 | 317 | ||
316 | if (qlcnic_get_mac_addr(adapter, &mac_addr) != 0) | 318 | if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0) |
317 | return -EIO; | 319 | return -EIO; |
318 | 320 | ||
319 | p = (unsigned char *)&mac_addr; | 321 | memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); |
320 | for (i = 0; i < 6; i++) | ||
321 | netdev->dev_addr[i] = *(p + 5 - i); | ||
322 | |||
323 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | 322 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); |
324 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | 323 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); |
325 | 324 | ||
@@ -371,6 +370,22 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
371 | #endif | 370 | #endif |
372 | }; | 371 | }; |
373 | 372 | ||
373 | static struct qlcnic_nic_template qlcnic_ops = { | ||
374 | .get_mac_addr = qlcnic_get_mac_addr, | ||
375 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
376 | .config_led = qlcnic_config_led, | ||
377 | .set_ilb_mode = qlcnic_set_ilb_mode, | ||
378 | .clear_ilb_mode = qlcnic_clear_ilb_mode | ||
379 | }; | ||
380 | |||
381 | static struct qlcnic_nic_template qlcnic_pf_ops = { | ||
382 | .get_mac_addr = qlcnic_get_mac_address, | ||
383 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
384 | .config_led = qlcnic_config_led, | ||
385 | .set_ilb_mode = qlcnic_set_ilb_mode, | ||
386 | .clear_ilb_mode = qlcnic_clear_ilb_mode | ||
387 | }; | ||
388 | |||
374 | static void | 389 | static void |
375 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) | 390 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) |
376 | { | 391 | { |
@@ -452,6 +467,125 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
452 | iounmap(adapter->ahw.pci_base0); | 467 | iounmap(adapter->ahw.pci_base0); |
453 | } | 468 | } |
454 | 469 | ||
470 | /* Use api lock to access this function */ | ||
471 | static int | ||
472 | qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | ||
473 | { | ||
474 | u8 id; | ||
475 | u32 ref_count; | ||
476 | int i, ret = 1; | ||
477 | u32 data = QLCNIC_MGMT_FUNC; | ||
478 | void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; | ||
479 | |||
480 | /* If other drivers are not in use set their privilege level */ | ||
481 | ref_count = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
482 | ret = qlcnic_api_lock(adapter); | ||
483 | if (ret) | ||
484 | goto err_lock; | ||
485 | if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func)) | ||
486 | goto err_npar; | ||
487 | |||
488 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
489 | id = adapter->npars[i].id; | ||
490 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC || | ||
491 | id == adapter->ahw.pci_func) | ||
492 | continue; | ||
493 | data |= (qlcnic_config_npars & QLC_DEV_SET_DRV(0xf, id)); | ||
494 | } | ||
495 | writel(data, priv_op); | ||
496 | |||
497 | err_npar: | ||
498 | qlcnic_api_unlock(adapter); | ||
499 | err_lock: | ||
500 | return ret; | ||
501 | } | ||
502 | |||
503 | static u8 | ||
504 | qlcnic_set_mgmt_driver(struct qlcnic_adapter *adapter) | ||
505 | { | ||
506 | u8 i, ret = 0; | ||
507 | |||
508 | if (qlcnic_get_pci_info(adapter)) | ||
509 | return ret; | ||
510 | /* Set the eswitch */ | ||
511 | for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++) { | ||
512 | if (!qlcnic_get_eswitch_capabilities(adapter, i, | ||
513 | &adapter->eswitch[i])) { | ||
514 | ret++; | ||
515 | qlcnic_toggle_eswitch(adapter, i, ret); | ||
516 | } | ||
517 | } | ||
518 | return ret; | ||
519 | } | ||
520 | |||
521 | static u32 | ||
522 | qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) | ||
523 | { | ||
524 | void __iomem *msix_base_addr; | ||
525 | void __iomem *priv_op; | ||
526 | u32 func; | ||
527 | u32 msix_base; | ||
528 | u32 op_mode, priv_level; | ||
529 | |||
530 | /* Determine FW API version */ | ||
531 | adapter->fw_hal_version = readl(adapter->ahw.pci_base0 + QLCNIC_FW_API); | ||
532 | if (adapter->fw_hal_version == ~0) { | ||
533 | adapter->nic_ops = &qlcnic_ops; | ||
534 | adapter->fw_hal_version = QLCNIC_FW_BASE; | ||
535 | adapter->ahw.pci_func = PCI_FUNC(adapter->pdev->devfn); | ||
536 | dev_info(&adapter->pdev->dev, | ||
537 | "FW does not support nic partion\n"); | ||
538 | return adapter->fw_hal_version; | ||
539 | } | ||
540 | |||
541 | /* Find PCI function number */ | ||
542 | pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func); | ||
543 | msix_base_addr = adapter->ahw.pci_base0 + QLCNIC_MSIX_BASE; | ||
544 | msix_base = readl(msix_base_addr); | ||
545 | func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; | ||
546 | adapter->ahw.pci_func = func; | ||
547 | |||
548 | /* Determine function privilege level */ | ||
549 | priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; | ||
550 | op_mode = readl(priv_op); | ||
551 | if (op_mode == QLC_DEV_DRV_DEFAULT) { | ||
552 | priv_level = QLCNIC_MGMT_FUNC; | ||
553 | if (qlcnic_api_lock(adapter)) | ||
554 | return 0; | ||
555 | op_mode = (op_mode & ~QLC_DEV_SET_DRV(0xf, func)) | | ||
556 | (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, func)); | ||
557 | writel(op_mode, priv_op); | ||
558 | qlcnic_api_unlock(adapter); | ||
559 | |||
560 | } else | ||
561 | priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); | ||
562 | |||
563 | switch (priv_level) { | ||
564 | case QLCNIC_MGMT_FUNC: | ||
565 | adapter->op_mode = QLCNIC_MGMT_FUNC; | ||
566 | adapter->nic_ops = &qlcnic_pf_ops; | ||
567 | /* Set privilege level for other functions */ | ||
568 | if (qlcnic_config_npars) | ||
569 | qlcnic_set_function_modes(adapter); | ||
570 | dev_info(&adapter->pdev->dev, | ||
571 | "HAL Version: %d, Management function\n", | ||
572 | adapter->fw_hal_version); | ||
573 | break; | ||
574 | case QLCNIC_PRIV_FUNC: | ||
575 | adapter->op_mode = QLCNIC_PRIV_FUNC; | ||
576 | dev_info(&adapter->pdev->dev, | ||
577 | "HAL Version: %d, Privileged function\n", | ||
578 | adapter->fw_hal_version); | ||
579 | adapter->nic_ops = &qlcnic_pf_ops; | ||
580 | break; | ||
581 | default: | ||
582 | dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n", | ||
583 | priv_level); | ||
584 | return 0; | ||
585 | } | ||
586 | return adapter->fw_hal_version; | ||
587 | } | ||
588 | |||
455 | static int | 589 | static int |
456 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | 590 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) |
457 | { | 591 | { |
@@ -460,7 +594,6 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | |||
460 | unsigned long mem_len, pci_len0 = 0; | 594 | unsigned long mem_len, pci_len0 = 0; |
461 | 595 | ||
462 | struct pci_dev *pdev = adapter->pdev; | 596 | struct pci_dev *pdev = adapter->pdev; |
463 | int pci_func = adapter->ahw.pci_func; | ||
464 | 597 | ||
465 | /* remap phys address */ | 598 | /* remap phys address */ |
466 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 599 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
@@ -483,8 +616,13 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | |||
483 | adapter->ahw.pci_base0 = mem_ptr0; | 616 | adapter->ahw.pci_base0 = mem_ptr0; |
484 | adapter->ahw.pci_len0 = pci_len0; | 617 | adapter->ahw.pci_len0 = pci_len0; |
485 | 618 | ||
619 | if (!qlcnic_get_driver_mode(adapter)) { | ||
620 | iounmap(adapter->ahw.pci_base0); | ||
621 | return -EIO; | ||
622 | } | ||
623 | |||
486 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, | 624 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, |
487 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | 625 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); |
488 | 626 | ||
489 | return 0; | 627 | return 0; |
490 | } | 628 | } |
@@ -553,7 +691,10 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
553 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", | 691 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", |
554 | fw_major, fw_minor, fw_build); | 692 | fw_major, fw_minor, fw_build); |
555 | 693 | ||
556 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | 694 | if (adapter->fw_hal_version == QLCNIC_FW_NPAR) |
695 | qlcnic_get_nic_info(adapter, adapter->ahw.pci_func); | ||
696 | else | ||
697 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
557 | 698 | ||
558 | adapter->flags &= ~QLCNIC_LRO_ENABLED; | 699 | adapter->flags &= ~QLCNIC_LRO_ENABLED; |
559 | 700 | ||
@@ -633,6 +774,10 @@ wait_init: | |||
633 | 774 | ||
634 | qlcnic_check_options(adapter); | 775 | qlcnic_check_options(adapter); |
635 | 776 | ||
777 | if (adapter->fw_hal_version != QLCNIC_FW_BASE && | ||
778 | adapter->op_mode == QLCNIC_MGMT_FUNC) | ||
779 | qlcnic_set_mgmt_driver(adapter); | ||
780 | |||
636 | adapter->need_fw_reset = 0; | 781 | adapter->need_fw_reset = 0; |
637 | 782 | ||
638 | qlcnic_release_firmware(adapter); | 783 | qlcnic_release_firmware(adapter); |
@@ -977,12 +1122,11 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, | |||
977 | 1122 | ||
978 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); | 1123 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); |
979 | 1124 | ||
980 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | 1125 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
981 | netdev->features |= (NETIF_F_GRO); | 1126 | NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6); |
982 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
983 | 1127 | ||
984 | netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | 1128 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
985 | netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | 1129 | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6); |
986 | 1130 | ||
987 | if (pci_using_dac) { | 1131 | if (pci_using_dac) { |
988 | netdev->features |= NETIF_F_HIGHDMA; | 1132 | netdev->features |= NETIF_F_HIGHDMA; |
@@ -1036,7 +1180,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1036 | struct net_device *netdev = NULL; | 1180 | struct net_device *netdev = NULL; |
1037 | struct qlcnic_adapter *adapter = NULL; | 1181 | struct qlcnic_adapter *adapter = NULL; |
1038 | int err; | 1182 | int err; |
1039 | int pci_func_id = PCI_FUNC(pdev->devfn); | ||
1040 | uint8_t revision_id; | 1183 | uint8_t revision_id; |
1041 | uint8_t pci_using_dac; | 1184 | uint8_t pci_using_dac; |
1042 | 1185 | ||
@@ -1072,7 +1215,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1072 | adapter->netdev = netdev; | 1215 | adapter->netdev = netdev; |
1073 | adapter->pdev = pdev; | 1216 | adapter->pdev = pdev; |
1074 | adapter->dev_rst_time = jiffies; | 1217 | adapter->dev_rst_time = jiffies; |
1075 | adapter->ahw.pci_func = pci_func_id; | ||
1076 | 1218 | ||
1077 | revision_id = pdev->revision; | 1219 | revision_id = pdev->revision; |
1078 | adapter->ahw.revision_id = revision_id; | 1220 | adapter->ahw.revision_id = revision_id; |
@@ -1088,7 +1230,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1088 | goto err_out_free_netdev; | 1230 | goto err_out_free_netdev; |
1089 | 1231 | ||
1090 | /* This will be reset for mezz cards */ | 1232 | /* This will be reset for mezz cards */ |
1091 | adapter->portnum = pci_func_id; | 1233 | adapter->portnum = adapter->ahw.pci_func; |
1092 | 1234 | ||
1093 | err = qlcnic_get_board_info(adapter); | 1235 | err = qlcnic_get_board_info(adapter); |
1094 | if (err) { | 1236 | if (err) { |
@@ -1175,6 +1317,11 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) | |||
1175 | 1317 | ||
1176 | qlcnic_detach(adapter); | 1318 | qlcnic_detach(adapter); |
1177 | 1319 | ||
1320 | if (adapter->npars != NULL) | ||
1321 | kfree(adapter->npars); | ||
1322 | if (adapter->eswitch != NULL) | ||
1323 | kfree(adapter->eswitch); | ||
1324 | |||
1178 | qlcnic_clr_all_drv_state(adapter); | 1325 | qlcnic_clr_all_drv_state(adapter); |
1179 | 1326 | ||
1180 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 1327 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
@@ -1340,11 +1487,11 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1340 | u8 opcode = TX_ETHER_PKT; | 1487 | u8 opcode = TX_ETHER_PKT; |
1341 | __be16 protocol = skb->protocol; | 1488 | __be16 protocol = skb->protocol; |
1342 | u16 flags = 0, vid = 0; | 1489 | u16 flags = 0, vid = 0; |
1343 | u32 producer; | ||
1344 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; | 1490 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; |
1345 | struct cmd_desc_type0 *hwdesc; | 1491 | struct cmd_desc_type0 *hwdesc; |
1346 | struct vlan_ethhdr *vh; | 1492 | struct vlan_ethhdr *vh; |
1347 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1493 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1494 | u32 producer = tx_ring->producer; | ||
1348 | 1495 | ||
1349 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | 1496 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { |
1350 | 1497 | ||
@@ -1360,6 +1507,11 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1360 | vlan_oob = 1; | 1507 | vlan_oob = 1; |
1361 | } | 1508 | } |
1362 | 1509 | ||
1510 | if (*(skb->data) & BIT_0) { | ||
1511 | flags |= BIT_0; | ||
1512 | memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); | ||
1513 | } | ||
1514 | |||
1363 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && | 1515 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && |
1364 | skb_shinfo(skb)->gso_size > 0) { | 1516 | skb_shinfo(skb)->gso_size > 0) { |
1365 | 1517 | ||
@@ -1409,7 +1561,6 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1409 | /* For LSO, we need to copy the MAC/IP/TCP headers into | 1561 | /* For LSO, we need to copy the MAC/IP/TCP headers into |
1410 | * the descriptor ring | 1562 | * the descriptor ring |
1411 | */ | 1563 | */ |
1412 | producer = tx_ring->producer; | ||
1413 | copied = 0; | 1564 | copied = 0; |
1414 | offset = 2; | 1565 | offset = 2; |
1415 | 1566 | ||
@@ -2382,7 +2533,7 @@ qlcnic_store_bridged_mode(struct device *dev, | |||
2382 | if (strict_strtoul(buf, 2, &new)) | 2533 | if (strict_strtoul(buf, 2, &new)) |
2383 | goto err_out; | 2534 | goto err_out; |
2384 | 2535 | ||
2385 | if (!qlcnic_config_bridged_mode(adapter, !!new)) | 2536 | if (!adapter->nic_ops->config_bridged_mode(adapter, !!new)) |
2386 | ret = len; | 2537 | ret = len; |
2387 | 2538 | ||
2388 | err_out: | 2539 | err_out: |