aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic/enic_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/enic/enic_main.c')
-rw-r--r--drivers/net/enic/enic_main.c50
1 files changed, 47 insertions, 3 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",