aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/enic')
-rw-r--r--drivers/net/enic/enic_main.c50
-rw-r--r--drivers/net/enic/vnic_dev.c19
-rw-r--r--drivers/net/enic/vnic_dev.h8
-rw-r--r--drivers/net/enic/vnic_rq.h7
4 files changed, 80 insertions, 4 deletions
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 2821a1db547..58cae6e6a59 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -851,6 +851,50 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
851 return 0; 851 return 0;
852} 852}
853 853
854static int enic_rq_alloc_buf_a1(struct vnic_rq *rq)
855{
856 struct rq_enet_desc *desc = vnic_rq_next_desc(rq);
857
858 if (vnic_rq_posting_soon(rq)) {
859
860 /* SW workaround for A0 HW erratum: if we're just about
861 * to write posted_index, insert a dummy desc
862 * of type resvd
863 */
864
865 rq_enet_desc_enc(desc, 0, RQ_ENET_TYPE_RESV2, 0);
866 vnic_rq_post(rq, 0, 0, 0, 0);
867 } else {
868 return enic_rq_alloc_buf(rq);
869 }
870
871 return 0;
872}
873
874static int enic_set_rq_alloc_buf(struct enic *enic)
875{
876 enum vnic_dev_hw_version hw_ver;
877 int err;
878
879 err = vnic_dev_hw_version(enic->vdev, &hw_ver);
880 if (err)
881 return err;
882
883 switch (hw_ver) {
884 case VNIC_DEV_HW_VER_A1:
885 enic->rq_alloc_buf = enic_rq_alloc_buf_a1;
886 break;
887 case VNIC_DEV_HW_VER_A2:
888 case VNIC_DEV_HW_VER_UNKNOWN:
889 enic->rq_alloc_buf = enic_rq_alloc_buf;
890 break;
891 default:
892 return -ENODEV;
893 }
894
895 return 0;
896}
897
854static int enic_get_skb_header(struct sk_buff *skb, void **iphdr, 898static int enic_get_skb_header(struct sk_buff *skb, void **iphdr,
855 void **tcph, u64 *hdr_flags, void *priv) 899 void **tcph, u64 *hdr_flags, void *priv)
856{ 900{
@@ -1058,7 +1102,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
1058 /* Replenish RQ 1102 /* Replenish RQ
1059 */ 1103 */
1060 1104
1061 vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf); 1105 vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
1062 1106
1063 } else { 1107 } else {
1064 1108
@@ -1093,7 +1137,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
1093 /* Replenish RQ 1137 /* Replenish RQ
1094 */ 1138 */
1095 1139
1096 vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf); 1140 vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
1097 1141
1098 /* Return intr event credits for this polling 1142 /* Return intr event credits for this polling
1099 * cycle. An intr event is the completion of a 1143 * cycle. An intr event is the completion of a
@@ -1269,7 +1313,7 @@ static int enic_open(struct net_device *netdev)
1269 } 1313 }
1270 1314
1271 for (i = 0; i < enic->rq_count; i++) { 1315 for (i = 0; i < enic->rq_count; i++) {
1272 err = vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf); 1316 err = vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf);
1273 if (err) { 1317 if (err) {
1274 printk(KERN_ERR PFX 1318 printk(KERN_ERR PFX
1275 "%s: Unable to alloc receive buffers.\n", 1319 "%s: Unable to alloc receive buffers.\n",
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index d5c28efedd9..c8d3fc7517b 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -349,6 +349,25 @@ int vnic_dev_fw_info(struct vnic_dev *vdev,
349 return err; 349 return err;
350} 350}
351 351
352int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver)
353{
354 struct vnic_devcmd_fw_info *fw_info;
355 int err;
356
357 err = vnic_dev_fw_info(vdev, &fw_info);
358 if (err)
359 return err;
360
361 if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0)
362 *hw_ver = VNIC_DEV_HW_VER_A1;
363 else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0)
364 *hw_ver = VNIC_DEV_HW_VER_A2;
365 else
366 *hw_ver = VNIC_DEV_HW_VER_UNKNOWN;
367
368 return 0;
369}
370
352int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, 371int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
353 void *value) 372 void *value)
354{ 373{
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index d960edb8cdf..db1d63e0b97 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -41,6 +41,12 @@ static inline void writeq(u64 val, void __iomem *reg)
41} 41}
42#endif 42#endif
43 43
44enum vnic_dev_hw_version {
45 VNIC_DEV_HW_VER_UNKNOWN,
46 VNIC_DEV_HW_VER_A1,
47 VNIC_DEV_HW_VER_A2,
48};
49
44enum vnic_dev_intr_mode { 50enum vnic_dev_intr_mode {
45 VNIC_DEV_INTR_MODE_UNKNOWN, 51 VNIC_DEV_INTR_MODE_UNKNOWN,
46 VNIC_DEV_INTR_MODE_INTX, 52 VNIC_DEV_INTR_MODE_INTX,
@@ -88,6 +94,8 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
88 u64 *a0, u64 *a1, int wait); 94 u64 *a0, u64 *a1, int wait);
89int vnic_dev_fw_info(struct vnic_dev *vdev, 95int vnic_dev_fw_info(struct vnic_dev *vdev,
90 struct vnic_devcmd_fw_info **fw_info); 96 struct vnic_devcmd_fw_info **fw_info);
97int vnic_dev_hw_version(struct vnic_dev *vdev,
98 enum vnic_dev_hw_version *hw_ver);
91int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, 99int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
92 void *value); 100 void *value);
93int vnic_dev_stats_clear(struct vnic_dev *vdev); 101int vnic_dev_stats_clear(struct vnic_dev *vdev);
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index fd0ef66d2e9..f7b5730cb74 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -143,6 +143,11 @@ static inline void vnic_rq_post(struct vnic_rq *rq,
143 } 143 }
144} 144}
145 145
146static inline int vnic_rq_posting_soon(struct vnic_rq *rq)
147{
148 return ((rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0);
149}
150
146static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count) 151static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count)
147{ 152{
148 rq->ring.desc_avail += count; 153 rq->ring.desc_avail += count;
@@ -186,7 +191,7 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
186{ 191{
187 int err; 192 int err;
188 193
189 while (vnic_rq_desc_avail(rq) > 1) { 194 while (vnic_rq_desc_avail(rq) > 0) {
190 195
191 err = (*buf_fill)(rq); 196 err = (*buf_fill)(rq);
192 if (err) 197 if (err)