diff options
author | Sony Chacko <sony.chacko@qlogic.com> | 2012-12-31 22:20:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-02 05:43:27 -0500 |
commit | 319ecf121e1da3d75dd1bde32fed255532e61797 (patch) | |
tree | 641d374501ebf30e2ad5a70c4e397d76e55a8bf1 /drivers/net/ethernet/qlogic/qlcnic | |
parent | 13159183ec7afe03ed48d3b083b255278f429b5a (diff) |
qlcnic: 83xx sysfs routines
Add 83xx sysfs interface routines
Update 82xx sysfs interface routines
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/qlcnic')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 60 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 56 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 254 |
6 files changed, 266 insertions, 122 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index dd9be4f008aa..6d51c24f341c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -1429,8 +1429,8 @@ int qlcnic_reset_context(struct qlcnic_adapter *); | |||
1429 | void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); | 1429 | void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); |
1430 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test); | 1430 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test); |
1431 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 1431 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
1432 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data); | 1432 | int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, size_t); |
1433 | int qlcnic_validate_max_rss(struct net_device *netdev, u8, u8); | 1433 | int qlcnic_validate_max_rss(u8, u8); |
1434 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); | 1434 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); |
1435 | int qlcnic_enable_msix(struct qlcnic_adapter *, u32); | 1435 | int qlcnic_enable_msix(struct qlcnic_adapter *, u32); |
1436 | 1436 | ||
@@ -1468,6 +1468,13 @@ void qlcnic_set_vlan_config(struct qlcnic_adapter *, | |||
1468 | struct qlcnic_esw_func_cfg *); | 1468 | struct qlcnic_esw_func_cfg *); |
1469 | void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *, | 1469 | void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *, |
1470 | struct qlcnic_esw_func_cfg *); | 1470 | struct qlcnic_esw_func_cfg *); |
1471 | void __qlcnic_down(struct qlcnic_adapter *, struct net_device *); | ||
1472 | void qlcnic_detach(struct qlcnic_adapter *); | ||
1473 | void qlcnic_teardown_intr(struct qlcnic_adapter *); | ||
1474 | int qlcnic_attach(struct qlcnic_adapter *); | ||
1475 | int __qlcnic_up(struct qlcnic_adapter *, struct net_device *); | ||
1476 | void qlcnic_restore_indev_addr(struct net_device *, unsigned long); | ||
1477 | |||
1471 | 1478 | ||
1472 | /* | 1479 | /* |
1473 | * QLOGIC Board information | 1480 | * QLOGIC Board information |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index b2b024c9f3ea..6d4d792e56d2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -242,6 +242,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { | |||
242 | .get_func_no = qlcnic_83xx_get_func_no, | 242 | .get_func_no = qlcnic_83xx_get_func_no, |
243 | .api_lock = qlcnic_83xx_cam_lock, | 243 | .api_lock = qlcnic_83xx_cam_lock, |
244 | .api_unlock = qlcnic_83xx_cam_unlock, | 244 | .api_unlock = qlcnic_83xx_cam_unlock, |
245 | .add_sysfs = qlcnic_83xx_add_sysfs, | ||
246 | .remove_sysfs = qlcnic_83xx_remove_sysfs, | ||
245 | .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag, | 247 | .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag, |
246 | .create_rx_ctx = qlcnic_83xx_create_rx_ctx, | 248 | .create_rx_ctx = qlcnic_83xx_create_rx_ctx, |
247 | .create_tx_ctx = qlcnic_83xx_create_tx_ctx, | 249 | .create_tx_ctx = qlcnic_83xx_create_tx_ctx, |
@@ -1154,6 +1156,64 @@ out: | |||
1154 | return err; | 1156 | return err; |
1155 | } | 1157 | } |
1156 | 1158 | ||
1159 | int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state, | ||
1160 | u32 beacon) | ||
1161 | { | ||
1162 | struct qlcnic_cmd_args cmd; | ||
1163 | u32 mbx_in; | ||
1164 | int i, status = 0; | ||
1165 | |||
1166 | if (state) { | ||
1167 | /* Get LED configuration */ | ||
1168 | qlcnic_alloc_mbx_args(&cmd, adapter, | ||
1169 | QLCNIC_CMD_GET_LED_CONFIG); | ||
1170 | status = qlcnic_issue_cmd(adapter, &cmd); | ||
1171 | if (status) { | ||
1172 | dev_err(&adapter->pdev->dev, | ||
1173 | "Get led config failed.\n"); | ||
1174 | goto mbx_err; | ||
1175 | } else { | ||
1176 | for (i = 0; i < 4; i++) | ||
1177 | adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1]; | ||
1178 | } | ||
1179 | qlcnic_free_mbx_args(&cmd); | ||
1180 | /* Set LED Configuration */ | ||
1181 | mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) | | ||
1182 | LSW(QLC_83XX_LED_CONFIG); | ||
1183 | qlcnic_alloc_mbx_args(&cmd, adapter, | ||
1184 | QLCNIC_CMD_SET_LED_CONFIG); | ||
1185 | cmd.req.arg[1] = mbx_in; | ||
1186 | cmd.req.arg[2] = mbx_in; | ||
1187 | cmd.req.arg[3] = mbx_in; | ||
1188 | if (beacon) | ||
1189 | cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON; | ||
1190 | status = qlcnic_issue_cmd(adapter, &cmd); | ||
1191 | if (status) { | ||
1192 | dev_err(&adapter->pdev->dev, | ||
1193 | "Set led config failed.\n"); | ||
1194 | } | ||
1195 | mbx_err: | ||
1196 | qlcnic_free_mbx_args(&cmd); | ||
1197 | return status; | ||
1198 | |||
1199 | } else { | ||
1200 | /* Restoring default LED configuration */ | ||
1201 | qlcnic_alloc_mbx_args(&cmd, adapter, | ||
1202 | QLCNIC_CMD_SET_LED_CONFIG); | ||
1203 | cmd.req.arg[1] = adapter->ahw->mbox_reg[0]; | ||
1204 | cmd.req.arg[2] = adapter->ahw->mbox_reg[1]; | ||
1205 | cmd.req.arg[3] = adapter->ahw->mbox_reg[2]; | ||
1206 | if (beacon) | ||
1207 | cmd.req.arg[4] = adapter->ahw->mbox_reg[3]; | ||
1208 | status = qlcnic_issue_cmd(adapter, &cmd); | ||
1209 | if (status) | ||
1210 | dev_err(&adapter->pdev->dev, | ||
1211 | "Restoring led config failed.\n"); | ||
1212 | qlcnic_free_mbx_args(&cmd); | ||
1213 | return status; | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1157 | void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter, | 1217 | void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter, |
1158 | int enable) | 1218 | int enable) |
1159 | { | 1219 | { |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 51775e4e3fd9..7af5a4686688 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -189,6 +189,8 @@ void qlcnic_83xx_get_func_no(struct qlcnic_adapter *); | |||
189 | int qlcnic_83xx_cam_lock(struct qlcnic_adapter *); | 189 | int qlcnic_83xx_cam_lock(struct qlcnic_adapter *); |
190 | void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *); | 190 | void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *); |
191 | int qlcnic_send_ctrl_op(struct qlcnic_adapter *, struct qlcnic_cmd_args *, u32); | 191 | int qlcnic_send_ctrl_op(struct qlcnic_adapter *, struct qlcnic_cmd_args *, u32); |
192 | void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *); | ||
193 | void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *); | ||
192 | void qlcnic_83xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t); | 194 | void qlcnic_83xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t); |
193 | void qlcnic_83xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t); | 195 | void qlcnic_83xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t); |
194 | int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong); | 196 | int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong); |
@@ -209,6 +211,7 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *, struct net_device *); | |||
209 | void qlcnic_83xx_napi_del(struct qlcnic_adapter *); | 211 | void qlcnic_83xx_napi_del(struct qlcnic_adapter *); |
210 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); | 212 | void qlcnic_83xx_napi_enable(struct qlcnic_adapter *); |
211 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); | 213 | void qlcnic_83xx_napi_disable(struct qlcnic_adapter *); |
214 | int qlcnic_83xx_config_led(struct qlcnic_adapter *, u32, u32); | ||
212 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); | 215 | void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); |
213 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); | 216 | int qlcnic_ind_rd(struct qlcnic_adapter *, u32); |
214 | void qlcnic_83xx_get_stats(struct qlcnic_adapter *, | 217 | void qlcnic_83xx_get_stats(struct qlcnic_adapter *, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 064f36b66b3e..920e33dc3add 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -529,11 +529,11 @@ static int qlcnic_set_channels(struct net_device *dev, | |||
529 | channel->tx_count != channel->max_tx) | 529 | channel->tx_count != channel->max_tx) |
530 | return -EINVAL; | 530 | return -EINVAL; |
531 | 531 | ||
532 | err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count); | 532 | err = qlcnic_validate_max_rss(channel->max_rx, channel->rx_count); |
533 | if (err) | 533 | if (err) |
534 | return err; | 534 | return err; |
535 | 535 | ||
536 | err = qlcnic_set_max_rss(adapter, channel->rx_count); | 536 | err = qlcnic_set_max_rss(adapter, channel->rx_count, 0); |
537 | netdev_info(dev, "allocated 0x%x sds rings\n", | 537 | netdev_info(dev, "allocated 0x%x sds rings\n", |
538 | adapter->max_sds_rings); | 538 | adapter->max_sds_rings); |
539 | return err; | 539 | return err; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 2e69ff8d4021..4a05dc0f74e9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -82,7 +82,6 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data); | |||
82 | static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data); | 82 | static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data); |
83 | 83 | ||
84 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); | 84 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); |
85 | static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long); | ||
86 | static int qlcnic_start_firmware(struct qlcnic_adapter *); | 85 | static int qlcnic_start_firmware(struct qlcnic_adapter *); |
87 | 86 | ||
88 | static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); | 87 | static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); |
@@ -181,6 +180,7 @@ static const struct qlcnic_board_info qlcnic_boards[] = { | |||
181 | }; | 180 | }; |
182 | 181 | ||
183 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards) | 182 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards) |
183 | #define QLC_MAX_SDS_RINGS 8 | ||
184 | 184 | ||
185 | static const | 185 | static const |
186 | struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG; | 186 | struct qlcnic_legacy_intr_set legacy_intr[] = QLCNIC_LEGACY_INTR_CONFIG; |
@@ -451,8 +451,7 @@ int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr) | |||
451 | return 0; | 451 | return 0; |
452 | } | 452 | } |
453 | 453 | ||
454 | static void | 454 | void qlcnic_teardown_intr(struct qlcnic_adapter *adapter) |
455 | qlcnic_teardown_intr(struct qlcnic_adapter *adapter) | ||
456 | { | 455 | { |
457 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | 456 | if (adapter->flags & QLCNIC_MSIX_ENABLED) |
458 | pci_disable_msix(adapter->pdev); | 457 | pci_disable_msix(adapter->pdev); |
@@ -1244,8 +1243,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter) | |||
1244 | } | 1243 | } |
1245 | } | 1244 | } |
1246 | 1245 | ||
1247 | static int | 1246 | int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) |
1248 | __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
1249 | { | 1247 | { |
1250 | int ring; | 1248 | int ring; |
1251 | u32 capab2; | 1249 | u32 capab2; |
@@ -1310,8 +1308,7 @@ static int qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1310 | return err; | 1308 | return err; |
1311 | } | 1309 | } |
1312 | 1310 | ||
1313 | static void | 1311 | void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) |
1314 | __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | ||
1315 | { | 1312 | { |
1316 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 1313 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) |
1317 | return; | 1314 | return; |
@@ -1353,7 +1350,7 @@ qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1353 | 1350 | ||
1354 | } | 1351 | } |
1355 | 1352 | ||
1356 | static int | 1353 | int |
1357 | qlcnic_attach(struct qlcnic_adapter *adapter) | 1354 | qlcnic_attach(struct qlcnic_adapter *adapter) |
1358 | { | 1355 | { |
1359 | struct net_device *netdev = adapter->netdev; | 1356 | struct net_device *netdev = adapter->netdev; |
@@ -1399,8 +1396,7 @@ err_out_napi_del: | |||
1399 | return err; | 1396 | return err; |
1400 | } | 1397 | } |
1401 | 1398 | ||
1402 | static void | 1399 | void qlcnic_detach(struct qlcnic_adapter *adapter) |
1403 | qlcnic_detach(struct qlcnic_adapter *adapter) | ||
1404 | { | 1400 | { |
1405 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 1401 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) |
1406 | return; | 1402 | return; |
@@ -2055,14 +2051,8 @@ done: | |||
2055 | static int qlcnic_open(struct net_device *netdev) | 2051 | static int qlcnic_open(struct net_device *netdev) |
2056 | { | 2052 | { |
2057 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 2053 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
2058 | u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
2059 | int err; | 2054 | int err; |
2060 | 2055 | ||
2061 | if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) { | ||
2062 | netdev_err(netdev, "Device in FAILED state\n"); | ||
2063 | return -EIO; | ||
2064 | } | ||
2065 | |||
2066 | netif_carrier_off(netdev); | 2056 | netif_carrier_off(netdev); |
2067 | 2057 | ||
2068 | err = qlcnic_attach(adapter); | 2058 | err = qlcnic_attach(adapter); |
@@ -3092,33 +3082,38 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) | |||
3092 | return err; | 3082 | return err; |
3093 | } | 3083 | } |
3094 | 3084 | ||
3095 | int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val) | 3085 | int qlcnic_validate_max_rss(u8 max_hw, u8 val) |
3096 | { | 3086 | { |
3097 | if (!qlcnic_use_msi_x && !qlcnic_use_msi) { | 3087 | u32 max_allowed; |
3098 | netdev_info(netdev, "no msix or msi support, hence no rss\n"); | 3088 | |
3099 | return -EINVAL; | 3089 | if (max_hw > QLC_MAX_SDS_RINGS) { |
3090 | max_hw = QLC_MAX_SDS_RINGS; | ||
3091 | pr_info("max rss reset to %d\n", QLC_MAX_SDS_RINGS); | ||
3100 | } | 3092 | } |
3101 | 3093 | ||
3102 | if ((val > max_hw) || (val < 2) || !is_power_of_2(val)) { | 3094 | max_allowed = rounddown_pow_of_two(min_t(int, max_hw, |
3103 | netdev_info(netdev, "rss_ring valid range [2 - %x] in " | 3095 | num_online_cpus())); |
3104 | " powers of 2\n", max_hw); | 3096 | if ((val > max_allowed) || (val < 2) || !is_power_of_2(val)) { |
3097 | pr_info("rss_ring valid range [2 - %x] in powers of 2\n", | ||
3098 | max_allowed); | ||
3105 | return -EINVAL; | 3099 | return -EINVAL; |
3106 | } | 3100 | } |
3107 | return 0; | 3101 | return 0; |
3108 | |||
3109 | } | 3102 | } |
3110 | 3103 | ||
3111 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data) | 3104 | int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, size_t len) |
3112 | { | 3105 | { |
3113 | int err; | 3106 | int err; |
3114 | struct net_device *netdev = adapter->netdev; | 3107 | struct net_device *netdev = adapter->netdev; |
3115 | 3108 | ||
3116 | rtnl_lock(); | 3109 | if (test_bit(__QLCNIC_RESETTING, &adapter->state)) |
3110 | return -EBUSY; | ||
3111 | |||
3117 | netif_device_detach(netdev); | 3112 | netif_device_detach(netdev); |
3118 | if (netif_running(netdev)) | 3113 | if (netif_running(netdev)) |
3119 | __qlcnic_down(adapter, netdev); | 3114 | __qlcnic_down(adapter, netdev); |
3120 | 3115 | ||
3121 | if (qlcnic_83xx_check(adapter)) { | 3116 | if (qlcnic_82xx_check(adapter)) { |
3122 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | 3117 | if (adapter->flags & QLCNIC_MSIX_ENABLED) |
3123 | qlcnic_83xx_config_intrpt(adapter, 0); | 3118 | qlcnic_83xx_config_intrpt(adapter, 0); |
3124 | qlcnic_83xx_free_mbx_intr(adapter); | 3119 | qlcnic_83xx_free_mbx_intr(adapter); |
@@ -3126,7 +3121,7 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data) | |||
3126 | 3121 | ||
3127 | qlcnic_detach(adapter); | 3122 | qlcnic_detach(adapter); |
3128 | qlcnic_teardown_intr(adapter); | 3123 | qlcnic_teardown_intr(adapter); |
3129 | err = adapter->ahw->hw_ops->setup_intr(adapter, data); | 3124 | err = qlcnic_setup_intr(adapter, data); |
3130 | if (err) | 3125 | if (err) |
3131 | dev_err(&adapter->pdev->dev, | 3126 | dev_err(&adapter->pdev->dev, |
3132 | "failed setting max_rss; rss disabled\n"); | 3127 | "failed setting max_rss; rss disabled\n"); |
@@ -3149,10 +3144,10 @@ int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data) | |||
3149 | goto done; | 3144 | goto done; |
3150 | qlcnic_restore_indev_addr(netdev, NETDEV_UP); | 3145 | qlcnic_restore_indev_addr(netdev, NETDEV_UP); |
3151 | } | 3146 | } |
3147 | err = len; | ||
3152 | done: | 3148 | done: |
3153 | netif_device_attach(netdev); | 3149 | netif_device_attach(netdev); |
3154 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 3150 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
3155 | rtnl_unlock(); | ||
3156 | return err; | 3151 | return err; |
3157 | } | 3152 | } |
3158 | 3153 | ||
@@ -3188,8 +3183,7 @@ qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, | |||
3188 | in_dev_put(indev); | 3183 | in_dev_put(indev); |
3189 | } | 3184 | } |
3190 | 3185 | ||
3191 | static void | 3186 | void qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) |
3192 | qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) | ||
3193 | { | 3187 | { |
3194 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 3188 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
3195 | struct net_device *dev; | 3189 | struct net_device *dev; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index eeefc73af7c2..504506349ac1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/interrupt.h> | 3 | #include <linux/interrupt.h> |
4 | 4 | ||
5 | #include "qlcnic.h" | 5 | #include "qlcnic.h" |
6 | #include "qlcnic_hw.h" | ||
6 | 7 | ||
7 | #include <linux/swab.h> | 8 | #include <linux/swab.h> |
8 | #include <linux/dma-mapping.h> | 9 | #include <linux/dma-mapping.h> |
@@ -13,6 +14,10 @@ | |||
13 | #include <linux/aer.h> | 14 | #include <linux/aer.h> |
14 | #include <linux/log2.h> | 15 | #include <linux/log2.h> |
15 | 16 | ||
17 | #include <linux/sysfs.h> | ||
18 | |||
19 | #define QLC_STATUS_UNSUPPORTED_CMD -2 | ||
20 | |||
16 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) | 21 | int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) |
17 | { | 22 | { |
18 | return -EOPNOTSUPP; | 23 | return -EOPNOTSUPP; |
@@ -40,7 +45,7 @@ static ssize_t qlcnic_store_bridged_mode(struct device *dev, | |||
40 | if (strict_strtoul(buf, 2, &new)) | 45 | if (strict_strtoul(buf, 2, &new)) |
41 | goto err_out; | 46 | goto err_out; |
42 | 47 | ||
43 | if (!adapter->nic_ops->config_bridged_mode(adapter, !!new)) | 48 | if (!qlcnic_config_bridged_mode(adapter, !!new)) |
44 | ret = len; | 49 | ret = len; |
45 | 50 | ||
46 | err_out: | 51 | err_out: |
@@ -80,9 +85,7 @@ static ssize_t qlcnic_show_diag_mode(struct device *dev, | |||
80 | struct device_attribute *attr, char *buf) | 85 | struct device_attribute *attr, char *buf) |
81 | { | 86 | { |
82 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 87 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
83 | 88 | return sprintf(buf, "%d\n", !!(adapter->flags & QLCNIC_DIAG_ENABLED)); | |
84 | return sprintf(buf, "%d\n", | ||
85 | !!(adapter->flags & QLCNIC_DIAG_ENABLED)); | ||
86 | } | 89 | } |
87 | 90 | ||
88 | static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon, | 91 | static int qlcnic_validate_beacon(struct qlcnic_adapter *adapter, u16 beacon, |
@@ -111,10 +114,11 @@ static ssize_t qlcnic_store_beacon(struct device *dev, | |||
111 | const char *buf, size_t len) | 114 | const char *buf, size_t len) |
112 | { | 115 | { |
113 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 116 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
114 | int max_sds_rings = adapter->max_sds_rings; | 117 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
118 | int err, max_sds_rings = adapter->max_sds_rings; | ||
115 | u16 beacon; | 119 | u16 beacon; |
116 | u8 b_state, b_rate; | 120 | u8 b_state, b_rate; |
117 | int err; | 121 | unsigned long h_beacon; |
118 | 122 | ||
119 | if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { | 123 | if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) { |
120 | dev_warn(dev, | 124 | dev_warn(dev, |
@@ -122,6 +126,41 @@ static ssize_t qlcnic_store_beacon(struct device *dev, | |||
122 | return -EOPNOTSUPP; | 126 | return -EOPNOTSUPP; |
123 | } | 127 | } |
124 | 128 | ||
129 | if (qlcnic_83xx_check(adapter) && | ||
130 | !test_bit(__QLCNIC_RESETTING, &adapter->state)) { | ||
131 | if (kstrtoul(buf, 2, &h_beacon)) | ||
132 | return -EINVAL; | ||
133 | |||
134 | if (ahw->beacon_state == h_beacon) | ||
135 | return len; | ||
136 | |||
137 | rtnl_lock(); | ||
138 | if (!ahw->beacon_state) { | ||
139 | if (test_and_set_bit(__QLCNIC_LED_ENABLE, | ||
140 | &adapter->state)) { | ||
141 | rtnl_unlock(); | ||
142 | return -EBUSY; | ||
143 | } | ||
144 | } | ||
145 | if (h_beacon) { | ||
146 | err = qlcnic_83xx_config_led(adapter, 1, h_beacon); | ||
147 | if (err) | ||
148 | goto beacon_err; | ||
149 | } else { | ||
150 | err = qlcnic_83xx_config_led(adapter, 0, !h_beacon); | ||
151 | if (err) | ||
152 | goto beacon_err; | ||
153 | } | ||
154 | /* set the current beacon state */ | ||
155 | ahw->beacon_state = h_beacon; | ||
156 | beacon_err: | ||
157 | if (!ahw->beacon_state) | ||
158 | clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); | ||
159 | |||
160 | rtnl_unlock(); | ||
161 | return len; | ||
162 | } | ||
163 | |||
125 | if (len != sizeof(u16)) | 164 | if (len != sizeof(u16)) |
126 | return QL_STATUS_INVALID_PARAM; | 165 | return QL_STATUS_INVALID_PARAM; |
127 | 166 | ||
@@ -154,11 +193,10 @@ static ssize_t qlcnic_store_beacon(struct device *dev, | |||
154 | } | 193 | } |
155 | 194 | ||
156 | err = qlcnic_config_led(adapter, b_state, b_rate); | 195 | err = qlcnic_config_led(adapter, b_state, b_rate); |
157 | 196 | if (!err) | |
158 | if (!err) { | ||
159 | err = len; | 197 | err = len; |
160 | adapter->ahw->beacon_state = b_state; | 198 | else |
161 | } | 199 | ahw->beacon_state = b_state; |
162 | 200 | ||
163 | if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) | 201 | if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) |
164 | qlcnic_diag_free_res(adapter->netdev, max_sds_rings); | 202 | qlcnic_diag_free_res(adapter->netdev, max_sds_rings); |
@@ -207,21 +245,13 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, | |||
207 | { | 245 | { |
208 | struct device *dev = container_of(kobj, struct device, kobj); | 246 | struct device *dev = container_of(kobj, struct device, kobj); |
209 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 247 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
210 | u32 data; | ||
211 | u64 qmdata; | ||
212 | int ret; | 248 | int ret; |
213 | 249 | ||
214 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | 250 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); |
215 | if (ret != 0) | 251 | if (ret != 0) |
216 | return ret; | 252 | return ret; |
253 | qlcnic_read_crb(adapter, buf, offset, size); | ||
217 | 254 | ||
218 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { | ||
219 | qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata); | ||
220 | memcpy(buf, &qmdata, size); | ||
221 | } else { | ||
222 | data = QLCRD32(adapter, offset); | ||
223 | memcpy(buf, &data, size); | ||
224 | } | ||
225 | return size; | 255 | return size; |
226 | } | 256 | } |
227 | 257 | ||
@@ -231,21 +261,13 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, | |||
231 | { | 261 | { |
232 | struct device *dev = container_of(kobj, struct device, kobj); | 262 | struct device *dev = container_of(kobj, struct device, kobj); |
233 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 263 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
234 | u32 data; | ||
235 | u64 qmdata; | ||
236 | int ret; | 264 | int ret; |
237 | 265 | ||
238 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | 266 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); |
239 | if (ret != 0) | 267 | if (ret != 0) |
240 | return ret; | 268 | return ret; |
241 | 269 | ||
242 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { | 270 | qlcnic_write_crb(adapter, buf, offset, size); |
243 | memcpy(&qmdata, buf, size); | ||
244 | qlcnic_pci_camqm_write_2M(adapter, offset, qmdata); | ||
245 | } else { | ||
246 | memcpy(&data, buf, size); | ||
247 | QLCWR32(adapter, offset, data); | ||
248 | } | ||
249 | return size; | 271 | return size; |
250 | } | 272 | } |
251 | 273 | ||
@@ -303,33 +325,44 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, | |||
303 | return size; | 325 | return size; |
304 | } | 326 | } |
305 | 327 | ||
328 | static int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | ||
329 | { | ||
330 | int i; | ||
331 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { | ||
332 | if (adapter->npars[i].pci_func == pci_func) | ||
333 | return i; | ||
334 | } | ||
335 | |||
336 | return -1; | ||
337 | } | ||
338 | |||
306 | static int validate_pm_config(struct qlcnic_adapter *adapter, | 339 | static int validate_pm_config(struct qlcnic_adapter *adapter, |
307 | struct qlcnic_pm_func_cfg *pm_cfg, int count) | 340 | struct qlcnic_pm_func_cfg *pm_cfg, int count) |
308 | { | 341 | { |
309 | u8 src_pci_func, s_esw_id, d_esw_id, dest_pci_func; | 342 | u8 src_pci_func, s_esw_id, d_esw_id; |
310 | int i; | 343 | u8 dest_pci_func; |
344 | int i, src_index, dest_index; | ||
311 | 345 | ||
312 | for (i = 0; i < count; i++) { | 346 | for (i = 0; i < count; i++) { |
313 | src_pci_func = pm_cfg[i].pci_func; | 347 | src_pci_func = pm_cfg[i].pci_func; |
314 | dest_pci_func = pm_cfg[i].dest_npar; | 348 | dest_pci_func = pm_cfg[i].dest_npar; |
315 | if (src_pci_func >= QLCNIC_MAX_PCI_FUNC || | 349 | src_index = qlcnic_is_valid_nic_func(adapter, src_pci_func); |
316 | dest_pci_func >= QLCNIC_MAX_PCI_FUNC) | ||
317 | return QL_STATUS_INVALID_PARAM; | ||
318 | 350 | ||
319 | if (adapter->npars[src_pci_func].type != QLCNIC_TYPE_NIC) | 351 | if (src_index < 0) |
320 | return QL_STATUS_INVALID_PARAM; | 352 | return QL_STATUS_INVALID_PARAM; |
321 | 353 | ||
322 | if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) | 354 | dest_index = qlcnic_is_valid_nic_func(adapter, dest_pci_func); |
355 | if (dest_index < 0) | ||
323 | return QL_STATUS_INVALID_PARAM; | 356 | return QL_STATUS_INVALID_PARAM; |
324 | 357 | ||
325 | s_esw_id = adapter->npars[src_pci_func].phy_port; | 358 | s_esw_id = adapter->npars[src_index].phy_port; |
326 | d_esw_id = adapter->npars[dest_pci_func].phy_port; | 359 | d_esw_id = adapter->npars[dest_index].phy_port; |
327 | 360 | ||
328 | if (s_esw_id != d_esw_id) | 361 | if (s_esw_id != d_esw_id) |
329 | return QL_STATUS_INVALID_PARAM; | 362 | return QL_STATUS_INVALID_PARAM; |
330 | } | 363 | } |
331 | return 0; | ||
332 | 364 | ||
365 | return 0; | ||
333 | } | 366 | } |
334 | 367 | ||
335 | static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | 368 | static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, |
@@ -342,7 +375,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
342 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 375 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
343 | struct qlcnic_pm_func_cfg *pm_cfg; | 376 | struct qlcnic_pm_func_cfg *pm_cfg; |
344 | u32 id, action, pci_func; | 377 | u32 id, action, pci_func; |
345 | int count, rem, i, ret; | 378 | int count, rem, i, ret, index; |
346 | 379 | ||
347 | count = size / sizeof(struct qlcnic_pm_func_cfg); | 380 | count = size / sizeof(struct qlcnic_pm_func_cfg); |
348 | rem = size % sizeof(struct qlcnic_pm_func_cfg); | 381 | rem = size % sizeof(struct qlcnic_pm_func_cfg); |
@@ -350,26 +383,32 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp, | |||
350 | return QL_STATUS_INVALID_PARAM; | 383 | return QL_STATUS_INVALID_PARAM; |
351 | 384 | ||
352 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; | 385 | pm_cfg = (struct qlcnic_pm_func_cfg *)buf; |
353 | |||
354 | ret = validate_pm_config(adapter, pm_cfg, count); | 386 | ret = validate_pm_config(adapter, pm_cfg, count); |
387 | |||
355 | if (ret) | 388 | if (ret) |
356 | return ret; | 389 | return ret; |
357 | for (i = 0; i < count; i++) { | 390 | for (i = 0; i < count; i++) { |
358 | pci_func = pm_cfg[i].pci_func; | 391 | pci_func = pm_cfg[i].pci_func; |
359 | action = !!pm_cfg[i].action; | 392 | action = !!pm_cfg[i].action; |
360 | id = adapter->npars[pci_func].phy_port; | 393 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
361 | ret = qlcnic_config_port_mirroring(adapter, id, action, | 394 | if (index < 0) |
362 | pci_func); | 395 | return QL_STATUS_INVALID_PARAM; |
396 | |||
397 | id = adapter->npars[index].phy_port; | ||
398 | ret = qlcnic_config_port_mirroring(adapter, id, | ||
399 | action, pci_func); | ||
363 | if (ret) | 400 | if (ret) |
364 | return ret; | 401 | return ret; |
365 | } | 402 | } |
366 | 403 | ||
367 | for (i = 0; i < count; i++) { | 404 | for (i = 0; i < count; i++) { |
368 | pci_func = pm_cfg[i].pci_func; | 405 | pci_func = pm_cfg[i].pci_func; |
369 | id = adapter->npars[pci_func].phy_port; | 406 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
370 | adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action; | 407 | id = adapter->npars[index].phy_port; |
371 | adapter->npars[pci_func].dest_npar = id; | 408 | adapter->npars[index].enable_pm = !!pm_cfg[i].action; |
409 | adapter->npars[index].dest_npar = id; | ||
372 | } | 410 | } |
411 | |||
373 | return size; | 412 | return size; |
374 | } | 413 | } |
375 | 414 | ||
@@ -383,16 +422,19 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp, | |||
383 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 422 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
384 | struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; | 423 | struct qlcnic_pm_func_cfg pm_cfg[QLCNIC_MAX_PCI_FUNC]; |
385 | int i; | 424 | int i; |
425 | u8 pci_func; | ||
386 | 426 | ||
387 | if (size != sizeof(pm_cfg)) | 427 | if (size != sizeof(pm_cfg)) |
388 | return QL_STATUS_INVALID_PARAM; | 428 | return QL_STATUS_INVALID_PARAM; |
389 | 429 | ||
390 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 430 | memset(&pm_cfg, 0, |
391 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | 431 | sizeof(struct qlcnic_pm_func_cfg) * QLCNIC_MAX_PCI_FUNC); |
392 | continue; | 432 | |
393 | pm_cfg[i].action = adapter->npars[i].enable_pm; | 433 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { |
394 | pm_cfg[i].dest_npar = 0; | 434 | pci_func = adapter->npars[i].pci_func; |
395 | pm_cfg[i].pci_func = i; | 435 | pm_cfg[pci_func].action = adapter->npars[i].enable_pm; |
436 | pm_cfg[pci_func].dest_npar = 0; | ||
437 | pm_cfg[pci_func].pci_func = i; | ||
396 | } | 438 | } |
397 | memcpy(buf, &pm_cfg, size); | 439 | memcpy(buf, &pm_cfg, size); |
398 | 440 | ||
@@ -404,24 +446,33 @@ static int validate_esw_config(struct qlcnic_adapter *adapter, | |||
404 | { | 446 | { |
405 | u32 op_mode; | 447 | u32 op_mode; |
406 | u8 pci_func; | 448 | u8 pci_func; |
407 | int i; | 449 | int i, ret; |
408 | 450 | ||
409 | op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); | 451 | if (qlcnic_82xx_check(adapter)) |
452 | op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE); | ||
453 | else | ||
454 | op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); | ||
410 | 455 | ||
411 | for (i = 0; i < count; i++) { | 456 | for (i = 0; i < count; i++) { |
412 | pci_func = esw_cfg[i].pci_func; | 457 | pci_func = esw_cfg[i].pci_func; |
413 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | 458 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) |
414 | return QL_STATUS_INVALID_PARAM; | 459 | return QL_STATUS_INVALID_PARAM; |
415 | 460 | ||
416 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) { | 461 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) |
417 | if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) | 462 | if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0) |
418 | return QL_STATUS_INVALID_PARAM; | 463 | return QL_STATUS_INVALID_PARAM; |
419 | } | ||
420 | 464 | ||
421 | switch (esw_cfg[i].op_mode) { | 465 | switch (esw_cfg[i].op_mode) { |
422 | case QLCNIC_PORT_DEFAULTS: | 466 | case QLCNIC_PORT_DEFAULTS: |
423 | if (QLC_DEV_GET_DRV(op_mode, pci_func) != | 467 | if (qlcnic_82xx_check(adapter)) { |
424 | QLCNIC_NON_PRIV_FUNC) { | 468 | ret = QLC_DEV_GET_DRV(op_mode, pci_func); |
469 | } else { | ||
470 | ret = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode, | ||
471 | pci_func); | ||
472 | esw_cfg[i].offload_flags = 0; | ||
473 | } | ||
474 | |||
475 | if (ret != QLCNIC_NON_PRIV_FUNC) { | ||
425 | if (esw_cfg[i].mac_anti_spoof != 0) | 476 | if (esw_cfg[i].mac_anti_spoof != 0) |
426 | return QL_STATUS_INVALID_PARAM; | 477 | return QL_STATUS_INVALID_PARAM; |
427 | if (esw_cfg[i].mac_override != 1) | 478 | if (esw_cfg[i].mac_override != 1) |
@@ -444,6 +495,7 @@ static int validate_esw_config(struct qlcnic_adapter *adapter, | |||
444 | return QL_STATUS_INVALID_PARAM; | 495 | return QL_STATUS_INVALID_PARAM; |
445 | } | 496 | } |
446 | } | 497 | } |
498 | |||
447 | return 0; | 499 | return 0; |
448 | } | 500 | } |
449 | 501 | ||
@@ -458,7 +510,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
458 | struct qlcnic_esw_func_cfg *esw_cfg; | 510 | struct qlcnic_esw_func_cfg *esw_cfg; |
459 | struct qlcnic_npar_info *npar; | 511 | struct qlcnic_npar_info *npar; |
460 | int count, rem, i, ret; | 512 | int count, rem, i, ret; |
461 | u8 pci_func, op_mode = 0; | 513 | int index; |
514 | u8 op_mode = 0, pci_func; | ||
462 | 515 | ||
463 | count = size / sizeof(struct qlcnic_esw_func_cfg); | 516 | count = size / sizeof(struct qlcnic_esw_func_cfg); |
464 | rem = size % sizeof(struct qlcnic_esw_func_cfg); | 517 | rem = size % sizeof(struct qlcnic_esw_func_cfg); |
@@ -471,10 +524,9 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
471 | return ret; | 524 | return ret; |
472 | 525 | ||
473 | for (i = 0; i < count; i++) { | 526 | for (i = 0; i < count; i++) { |
474 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) { | 527 | if (adapter->ahw->op_mode == QLCNIC_MGMT_FUNC) |
475 | if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) | 528 | if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) |
476 | return QL_STATUS_INVALID_PARAM; | 529 | return QL_STATUS_INVALID_PARAM; |
477 | } | ||
478 | 530 | ||
479 | if (adapter->ahw->pci_func != esw_cfg[i].pci_func) | 531 | if (adapter->ahw->pci_func != esw_cfg[i].pci_func) |
480 | continue; | 532 | continue; |
@@ -503,7 +555,8 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file, | |||
503 | 555 | ||
504 | for (i = 0; i < count; i++) { | 556 | for (i = 0; i < count; i++) { |
505 | pci_func = esw_cfg[i].pci_func; | 557 | pci_func = esw_cfg[i].pci_func; |
506 | npar = &adapter->npars[pci_func]; | 558 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
559 | npar = &adapter->npars[index]; | ||
507 | switch (esw_cfg[i].op_mode) { | 560 | switch (esw_cfg[i].op_mode) { |
508 | case QLCNIC_PORT_DEFAULTS: | 561 | case QLCNIC_PORT_DEFAULTS: |
509 | npar->promisc_mode = esw_cfg[i].promisc_mode; | 562 | npar->promisc_mode = esw_cfg[i].promisc_mode; |
@@ -533,18 +586,21 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file, | |||
533 | struct device *dev = container_of(kobj, struct device, kobj); | 586 | struct device *dev = container_of(kobj, struct device, kobj); |
534 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 587 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
535 | struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; | 588 | struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; |
536 | u8 i; | 589 | u8 i, pci_func; |
537 | 590 | ||
538 | if (size != sizeof(esw_cfg)) | 591 | if (size != sizeof(esw_cfg)) |
539 | return QL_STATUS_INVALID_PARAM; | 592 | return QL_STATUS_INVALID_PARAM; |
540 | 593 | ||
541 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 594 | memset(&esw_cfg, 0, |
542 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | 595 | sizeof(struct qlcnic_esw_func_cfg) * QLCNIC_MAX_PCI_FUNC); |
543 | continue; | 596 | |
544 | esw_cfg[i].pci_func = i; | 597 | for (i = 0; i < adapter->ahw->act_pci_func; i++) { |
545 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i])) | 598 | pci_func = adapter->npars[i].pci_func; |
599 | esw_cfg[pci_func].pci_func = pci_func; | ||
600 | if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[pci_func])) | ||
546 | return QL_STATUS_INVALID_PARAM; | 601 | return QL_STATUS_INVALID_PARAM; |
547 | } | 602 | } |
603 | |||
548 | memcpy(buf, &esw_cfg, size); | 604 | memcpy(buf, &esw_cfg, size); |
549 | 605 | ||
550 | return size; | 606 | return size; |
@@ -558,10 +614,7 @@ static int validate_npar_config(struct qlcnic_adapter *adapter, | |||
558 | 614 | ||
559 | for (i = 0; i < count; i++) { | 615 | for (i = 0; i < count; i++) { |
560 | pci_func = np_cfg[i].pci_func; | 616 | pci_func = np_cfg[i].pci_func; |
561 | if (pci_func >= QLCNIC_MAX_PCI_FUNC) | 617 | if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0) |
562 | return QL_STATUS_INVALID_PARAM; | ||
563 | |||
564 | if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) | ||
565 | return QL_STATUS_INVALID_PARAM; | 618 | return QL_STATUS_INVALID_PARAM; |
566 | 619 | ||
567 | if (!IS_VALID_BW(np_cfg[i].min_bw) || | 620 | if (!IS_VALID_BW(np_cfg[i].min_bw) || |
@@ -581,7 +634,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
581 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 634 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
582 | struct qlcnic_info nic_info; | 635 | struct qlcnic_info nic_info; |
583 | struct qlcnic_npar_func_cfg *np_cfg; | 636 | struct qlcnic_npar_func_cfg *np_cfg; |
584 | int i, count, rem, ret; | 637 | int i, count, rem, ret, index; |
585 | u8 pci_func; | 638 | u8 pci_func; |
586 | 639 | ||
587 | count = size / sizeof(struct qlcnic_npar_func_cfg); | 640 | count = size / sizeof(struct qlcnic_npar_func_cfg); |
@@ -594,8 +647,10 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
594 | if (ret) | 647 | if (ret) |
595 | return ret; | 648 | return ret; |
596 | 649 | ||
597 | for (i = 0; i < count ; i++) { | 650 | for (i = 0; i < count; i++) { |
598 | pci_func = np_cfg[i].pci_func; | 651 | pci_func = np_cfg[i].pci_func; |
652 | |||
653 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | ||
599 | ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); | 654 | ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); |
600 | if (ret) | 655 | if (ret) |
601 | return ret; | 656 | return ret; |
@@ -605,12 +660,12 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file, | |||
605 | ret = qlcnic_set_nic_info(adapter, &nic_info); | 660 | ret = qlcnic_set_nic_info(adapter, &nic_info); |
606 | if (ret) | 661 | if (ret) |
607 | return ret; | 662 | return ret; |
608 | adapter->npars[i].min_bw = nic_info.min_tx_bw; | 663 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
609 | adapter->npars[i].max_bw = nic_info.max_tx_bw; | 664 | adapter->npars[index].min_bw = nic_info.min_tx_bw; |
665 | adapter->npars[index].max_bw = nic_info.max_tx_bw; | ||
610 | } | 666 | } |
611 | 667 | ||
612 | return size; | 668 | return size; |
613 | |||
614 | } | 669 | } |
615 | 670 | ||
616 | static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | 671 | static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, |
@@ -628,8 +683,12 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
628 | if (size != sizeof(np_cfg)) | 683 | if (size != sizeof(np_cfg)) |
629 | return QL_STATUS_INVALID_PARAM; | 684 | return QL_STATUS_INVALID_PARAM; |
630 | 685 | ||
686 | memset(&nic_info, 0, sizeof(struct qlcnic_info)); | ||
687 | memset(&np_cfg, 0, | ||
688 | sizeof(struct qlcnic_npar_func_cfg) * QLCNIC_MAX_PCI_FUNC); | ||
689 | |||
631 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | 690 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { |
632 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC) | 691 | if (qlcnic_is_valid_nic_func(adapter, i) < 0) |
633 | continue; | 692 | continue; |
634 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); | 693 | ret = qlcnic_get_nic_info(adapter, &nic_info, i); |
635 | if (ret) | 694 | if (ret) |
@@ -644,6 +703,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, | |||
644 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; | 703 | np_cfg[i].max_tx_queues = nic_info.max_tx_ques; |
645 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; | 704 | np_cfg[i].max_rx_queues = nic_info.max_rx_ques; |
646 | } | 705 | } |
706 | |||
647 | memcpy(buf, &np_cfg, size); | 707 | memcpy(buf, &np_cfg, size); |
648 | return size; | 708 | return size; |
649 | } | 709 | } |
@@ -659,6 +719,9 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file, | |||
659 | struct qlcnic_esw_statistics port_stats; | 719 | struct qlcnic_esw_statistics port_stats; |
660 | int ret; | 720 | int ret; |
661 | 721 | ||
722 | if (qlcnic_83xx_check(adapter)) | ||
723 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
724 | |||
662 | if (size != sizeof(struct qlcnic_esw_statistics)) | 725 | if (size != sizeof(struct qlcnic_esw_statistics)) |
663 | return QL_STATUS_INVALID_PARAM; | 726 | return QL_STATUS_INVALID_PARAM; |
664 | 727 | ||
@@ -691,6 +754,9 @@ static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file, | |||
691 | struct qlcnic_esw_statistics esw_stats; | 754 | struct qlcnic_esw_statistics esw_stats; |
692 | int ret; | 755 | int ret; |
693 | 756 | ||
757 | if (qlcnic_83xx_check(adapter)) | ||
758 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
759 | |||
694 | if (size != sizeof(struct qlcnic_esw_statistics)) | 760 | if (size != sizeof(struct qlcnic_esw_statistics)) |
695 | return QL_STATUS_INVALID_PARAM; | 761 | return QL_STATUS_INVALID_PARAM; |
696 | 762 | ||
@@ -722,6 +788,9 @@ static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file, | |||
722 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 788 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
723 | int ret; | 789 | int ret; |
724 | 790 | ||
791 | if (qlcnic_83xx_check(adapter)) | ||
792 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
793 | |||
725 | if (offset >= QLCNIC_NIU_MAX_XG_PORTS) | 794 | if (offset >= QLCNIC_NIU_MAX_XG_PORTS) |
726 | return QL_STATUS_INVALID_PARAM; | 795 | return QL_STATUS_INVALID_PARAM; |
727 | 796 | ||
@@ -744,10 +813,14 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file, | |||
744 | char *buf, loff_t offset, | 813 | char *buf, loff_t offset, |
745 | size_t size) | 814 | size_t size) |
746 | { | 815 | { |
816 | |||
747 | struct device *dev = container_of(kobj, struct device, kobj); | 817 | struct device *dev = container_of(kobj, struct device, kobj); |
748 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 818 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
749 | int ret; | 819 | int ret; |
750 | 820 | ||
821 | if (qlcnic_83xx_check(adapter)) | ||
822 | return QLC_STATUS_UNSUPPORTED_CMD; | ||
823 | |||
751 | if (offset >= QLCNIC_MAX_PCI_FUNC) | 824 | if (offset >= QLCNIC_MAX_PCI_FUNC) |
752 | return QL_STATUS_INVALID_PARAM; | 825 | return QL_STATUS_INVALID_PARAM; |
753 | 826 | ||
@@ -789,7 +862,10 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
789 | return ret; | 862 | return ret; |
790 | } | 863 | } |
791 | 864 | ||
792 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC ; i++) { | 865 | memset(&pci_cfg, 0, |
866 | sizeof(struct qlcnic_pci_func_cfg) * QLCNIC_MAX_PCI_FUNC); | ||
867 | |||
868 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
793 | pci_cfg[i].pci_func = pci_info[i].id; | 869 | pci_cfg[i].pci_func = pci_info[i].id; |
794 | pci_cfg[i].func_type = pci_info[i].type; | 870 | pci_cfg[i].func_type = pci_info[i].type; |
795 | pci_cfg[i].port_num = pci_info[i].default_port; | 871 | pci_cfg[i].port_num = pci_info[i].default_port; |
@@ -797,6 +873,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, | |||
797 | pci_cfg[i].max_bw = pci_info[i].tx_max_bw; | 873 | pci_cfg[i].max_bw = pci_info[i].tx_max_bw; |
798 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); | 874 | memcpy(&pci_cfg[i].def_mac_addr, &pci_info[i].mac, ETH_ALEN); |
799 | } | 875 | } |
876 | |||
800 | memcpy(buf, &pci_cfg, size); | 877 | memcpy(buf, &pci_cfg, size); |
801 | kfree(pci_info); | 878 | kfree(pci_info); |
802 | return size; | 879 | return size; |
@@ -897,7 +974,6 @@ void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter) | |||
897 | void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | 974 | void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) |
898 | { | 975 | { |
899 | struct device *dev = &adapter->pdev->dev; | 976 | struct device *dev = &adapter->pdev->dev; |
900 | u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
901 | 977 | ||
902 | if (device_create_bin_file(dev, &bin_attr_port_stats)) | 978 | if (device_create_bin_file(dev, &bin_attr_port_stats)) |
903 | dev_info(dev, "failed to create port stats sysfs entry"); | 979 | dev_info(dev, "failed to create port stats sysfs entry"); |
@@ -911,9 +987,6 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | |||
911 | if (device_create_bin_file(dev, &bin_attr_mem)) | 987 | if (device_create_bin_file(dev, &bin_attr_mem)) |
912 | dev_info(dev, "failed to create mem sysfs entry\n"); | 988 | dev_info(dev, "failed to create mem sysfs entry\n"); |
913 | 989 | ||
914 | if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) | ||
915 | return; | ||
916 | |||
917 | if (device_create_bin_file(dev, &bin_attr_pci_config)) | 990 | if (device_create_bin_file(dev, &bin_attr_pci_config)) |
918 | dev_info(dev, "failed to create pci config sysfs entry"); | 991 | dev_info(dev, "failed to create pci config sysfs entry"); |
919 | if (device_create_file(dev, &dev_attr_beacon)) | 992 | if (device_create_file(dev, &dev_attr_beacon)) |
@@ -936,7 +1009,6 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) | |||
936 | void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | 1009 | void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) |
937 | { | 1010 | { |
938 | struct device *dev = &adapter->pdev->dev; | 1011 | struct device *dev = &adapter->pdev->dev; |
939 | u32 state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | ||
940 | 1012 | ||
941 | device_remove_bin_file(dev, &bin_attr_port_stats); | 1013 | device_remove_bin_file(dev, &bin_attr_port_stats); |
942 | 1014 | ||
@@ -945,8 +1017,6 @@ void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) | |||
945 | device_remove_file(dev, &dev_attr_diag_mode); | 1017 | device_remove_file(dev, &dev_attr_diag_mode); |
946 | device_remove_bin_file(dev, &bin_attr_crb); | 1018 | device_remove_bin_file(dev, &bin_attr_crb); |
947 | device_remove_bin_file(dev, &bin_attr_mem); | 1019 | device_remove_bin_file(dev, &bin_attr_mem); |
948 | if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD)) | ||
949 | return; | ||
950 | device_remove_bin_file(dev, &bin_attr_pci_config); | 1020 | device_remove_bin_file(dev, &bin_attr_pci_config); |
951 | device_remove_file(dev, &dev_attr_beacon); | 1021 | device_remove_file(dev, &dev_attr_beacon); |
952 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) | 1022 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) |
@@ -968,3 +1038,13 @@ void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter) | |||
968 | { | 1038 | { |
969 | qlcnic_remove_diag_entries(adapter); | 1039 | qlcnic_remove_diag_entries(adapter); |
970 | } | 1040 | } |
1041 | |||
1042 | void qlcnic_83xx_add_sysfs(struct qlcnic_adapter *adapter) | ||
1043 | { | ||
1044 | qlcnic_create_diag_entries(adapter); | ||
1045 | } | ||
1046 | |||
1047 | void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *adapter) | ||
1048 | { | ||
1049 | qlcnic_remove_diag_entries(adapter); | ||
1050 | } | ||