diff options
author | Roopa Prabhu <roprabhu@cisco.com> | 2011-09-21 23:44:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-27 01:10:24 -0400 |
commit | 889d13f53cf9d741398637b6e8e578c65bb792e8 (patch) | |
tree | 9e87db0a201131d272cd18f5bfd24743eddb90de /drivers/net/ethernet/cisco | |
parent | 8749b427f213e14303dfef4c1b9770f05f67916d (diff) |
enic: Helper code for SRIOV proxy commands
This patch adds helper functions to use PF as proxy for SRIOV VF firmware
commands.
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: Sujith Sankar <ssujith@cisco.com>
Signed-off-by: Christian Benvenuti <benve@cisco.com>
Signed-off-by: David Wang <dwang2@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cisco')
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_dev.h | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/enic_main.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_dev.c | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_dev.h | 2 |
5 files changed, 54 insertions, 5 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index 13ff78e5a582..8c5cfb53b178 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h | |||
@@ -129,5 +129,6 @@ static inline struct device *enic_get_dev(struct enic *enic) | |||
129 | 129 | ||
130 | void enic_reset_addr_lists(struct enic *enic); | 130 | void enic_reset_addr_lists(struct enic *enic); |
131 | int enic_sriov_enabled(struct enic *enic); | 131 | int enic_sriov_enabled(struct enic *enic); |
132 | int enic_is_valid_vf(struct enic *enic, int vf); | ||
132 | 133 | ||
133 | #endif /* _ENIC_H_ */ | 134 | #endif /* _ENIC_H_ */ |
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.h b/drivers/net/ethernet/cisco/enic/enic_dev.h index ff8e87fdfc1d..1f83a4747ba0 100644 --- a/drivers/net/ethernet/cisco/enic/enic_dev.h +++ b/drivers/net/ethernet/cisco/enic/enic_dev.h | |||
@@ -19,6 +19,25 @@ | |||
19 | #ifndef _ENIC_DEV_H_ | 19 | #ifndef _ENIC_DEV_H_ |
20 | #define _ENIC_DEV_H_ | 20 | #define _ENIC_DEV_H_ |
21 | 21 | ||
22 | #include "vnic_dev.h" | ||
23 | |||
24 | /* | ||
25 | * Calls the devcmd function given by argument vnicdevcmdfn. | ||
26 | * If vf argument is valid, it proxies the devcmd | ||
27 | */ | ||
28 | #define ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnicdevcmdfn, ...) \ | ||
29 | do { \ | ||
30 | spin_lock(&enic->devcmd_lock); \ | ||
31 | if (enic_is_valid_vf(enic, vf)) { \ | ||
32 | vnic_dev_cmd_proxy_by_index_start(enic->vdev, vf); \ | ||
33 | err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \ | ||
34 | vnic_dev_cmd_proxy_end(enic->vdev); \ | ||
35 | } else { \ | ||
36 | err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \ | ||
37 | } \ | ||
38 | spin_unlock(&enic->devcmd_lock); \ | ||
39 | } while (0) | ||
40 | |||
22 | int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info); | 41 | int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info); |
23 | int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats); | 42 | int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats); |
24 | int enic_dev_add_station_addr(struct enic *enic); | 43 | int enic_dev_add_station_addr(struct enic *enic); |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index eced800c3429..59ba590c0526 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -132,6 +132,15 @@ int enic_sriov_enabled(struct enic *enic) | |||
132 | return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0; | 132 | return (enic->priv_flags & ENIC_SRIOV_ENABLED) ? 1 : 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | int enic_is_valid_vf(struct enic *enic, int vf) | ||
136 | { | ||
137 | #ifdef CONFIG_PCI_IOV | ||
138 | return vf >= 0 && vf < enic->num_vfs; | ||
139 | #else | ||
140 | return 0; | ||
141 | #endif | ||
142 | } | ||
143 | |||
135 | static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) | 144 | static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) |
136 | { | 145 | { |
137 | return rq; | 146 | return rq; |
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c index 8c4c8cf486f6..31e7f9bc2067 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.c +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c | |||
@@ -32,6 +32,7 @@ | |||
32 | enum vnic_proxy_type { | 32 | enum vnic_proxy_type { |
33 | PROXY_NONE, | 33 | PROXY_NONE, |
34 | PROXY_BY_BDF, | 34 | PROXY_BY_BDF, |
35 | PROXY_BY_INDEX, | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | struct vnic_res { | 38 | struct vnic_res { |
@@ -328,20 +329,21 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | |||
328 | return -ETIMEDOUT; | 329 | return -ETIMEDOUT; |
329 | } | 330 | } |
330 | 331 | ||
331 | static int vnic_dev_cmd_proxy_by_bdf(struct vnic_dev *vdev, | 332 | static int vnic_dev_cmd_proxy(struct vnic_dev *vdev, |
332 | enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait) | 333 | enum vnic_devcmd_cmd proxy_cmd, enum vnic_devcmd_cmd cmd, |
334 | u64 *a0, u64 *a1, int wait) | ||
333 | { | 335 | { |
334 | u32 status; | 336 | u32 status; |
335 | int err; | 337 | int err; |
336 | 338 | ||
337 | memset(vdev->args, 0, sizeof(vdev->args)); | 339 | memset(vdev->args, 0, sizeof(vdev->args)); |
338 | 340 | ||
339 | vdev->args[0] = vdev->proxy_index; /* bdf */ | 341 | vdev->args[0] = vdev->proxy_index; |
340 | vdev->args[1] = cmd; | 342 | vdev->args[1] = cmd; |
341 | vdev->args[2] = *a0; | 343 | vdev->args[2] = *a0; |
342 | vdev->args[3] = *a1; | 344 | vdev->args[3] = *a1; |
343 | 345 | ||
344 | err = _vnic_dev_cmd(vdev, CMD_PROXY_BY_BDF, wait); | 346 | err = _vnic_dev_cmd(vdev, proxy_cmd, wait); |
345 | if (err) | 347 | if (err) |
346 | return err; | 348 | return err; |
347 | 349 | ||
@@ -376,14 +378,30 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, | |||
376 | return err; | 378 | return err; |
377 | } | 379 | } |
378 | 380 | ||
381 | void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index) | ||
382 | { | ||
383 | vdev->proxy = PROXY_BY_INDEX; | ||
384 | vdev->proxy_index = index; | ||
385 | } | ||
386 | |||
387 | void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev) | ||
388 | { | ||
389 | vdev->proxy = PROXY_NONE; | ||
390 | vdev->proxy_index = 0; | ||
391 | } | ||
392 | |||
379 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | 393 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, |
380 | u64 *a0, u64 *a1, int wait) | 394 | u64 *a0, u64 *a1, int wait) |
381 | { | 395 | { |
382 | memset(vdev->args, 0, sizeof(vdev->args)); | 396 | memset(vdev->args, 0, sizeof(vdev->args)); |
383 | 397 | ||
384 | switch (vdev->proxy) { | 398 | switch (vdev->proxy) { |
399 | case PROXY_BY_INDEX: | ||
400 | return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd, | ||
401 | a0, a1, wait); | ||
385 | case PROXY_BY_BDF: | 402 | case PROXY_BY_BDF: |
386 | return vnic_dev_cmd_proxy_by_bdf(vdev, cmd, a0, a1, wait); | 403 | return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd, |
404 | a0, a1, wait); | ||
387 | case PROXY_NONE: | 405 | case PROXY_NONE: |
388 | default: | 406 | default: |
389 | return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait); | 407 | return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait); |
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h index 852b698fbe7d..6a138b625d13 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.h +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h | |||
@@ -85,6 +85,8 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev, | |||
85 | struct vnic_dev_ring *ring); | 85 | struct vnic_dev_ring *ring); |
86 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | 86 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, |
87 | u64 *a0, u64 *a1, int wait); | 87 | u64 *a0, u64 *a1, int wait); |
88 | void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index); | ||
89 | void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev); | ||
88 | int vnic_dev_fw_info(struct vnic_dev *vdev, | 90 | int vnic_dev_fw_info(struct vnic_dev *vdev, |
89 | struct vnic_devcmd_fw_info **fw_info); | 91 | struct vnic_devcmd_fw_info **fw_info); |
90 | int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, | 92 | int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, |