1
1
/* Broadcom NetXtreme-C/E network driver.
2
2
*
3
- * Copyright (c) 2016 Broadcom Limited
3
+ * Copyright (c) 2016-2018 Broadcom Limited
4
4
*
5
5
* This program is free software; you can redistribute it and/or modify
6
6
* it under the terms of the GNU General Public License as published by
@@ -101,13 +101,27 @@ static int bnxt_unregister_dev(struct bnxt_en_dev *edev, int ulp_id)
101
101
return 0 ;
102
102
}
103
103
104
+ static void bnxt_fill_msix_vecs (struct bnxt * bp , struct bnxt_msix_entry * ent )
105
+ {
106
+ struct bnxt_en_dev * edev = bp -> edev ;
107
+ int num_msix , idx , i ;
108
+
109
+ num_msix = edev -> ulp_tbl [BNXT_ROCE_ULP ].msix_requested ;
110
+ idx = edev -> ulp_tbl [BNXT_ROCE_ULP ].msix_base ;
111
+ for (i = 0 ; i < num_msix ; i ++ ) {
112
+ ent [i ].vector = bp -> irq_tbl [idx + i ].vector ;
113
+ ent [i ].ring_idx = idx + i ;
114
+ ent [i ].db_offset = (idx + i ) * 0x80 ;
115
+ }
116
+ }
117
+
104
118
static int bnxt_req_msix_vecs (struct bnxt_en_dev * edev , int ulp_id ,
105
119
struct bnxt_msix_entry * ent , int num_msix )
106
120
{
107
121
struct net_device * dev = edev -> net ;
108
122
struct bnxt * bp = netdev_priv (dev );
109
123
int max_idx , max_cp_rings ;
110
- int avail_msix , i , idx ;
124
+ int avail_msix , idx ;
111
125
int rc = 0 ;
112
126
113
127
ASSERT_RTNL ();
@@ -154,13 +168,10 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
154
168
avail_msix = hw_resc -> resv_cp_rings - bp -> cp_nr_rings ;
155
169
edev -> ulp_tbl [ulp_id ].msix_requested = avail_msix ;
156
170
}
157
- for (i = 0 ; i < avail_msix ; i ++ ) {
158
- ent [i ].vector = bp -> irq_tbl [idx + i ].vector ;
159
- ent [i ].ring_idx = idx + i ;
160
- ent [i ].db_offset = (idx + i ) * 0x80 ;
161
- }
171
+ bnxt_fill_msix_vecs (bp , ent );
162
172
bnxt_set_max_func_irqs (bp , bnxt_get_max_func_irqs (bp ) - avail_msix );
163
173
bnxt_set_max_func_cp_rings (bp , max_cp_rings - avail_msix );
174
+ edev -> flags |= BNXT_EN_FLAG_MSIX_REQUESTED ;
164
175
return avail_msix ;
165
176
}
166
177
@@ -174,11 +185,15 @@ static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, int ulp_id)
174
185
if (ulp_id != BNXT_ROCE_ULP )
175
186
return - EINVAL ;
176
187
188
+ if (!(edev -> flags & BNXT_EN_FLAG_MSIX_REQUESTED ))
189
+ return 0 ;
190
+
177
191
max_cp_rings = bnxt_get_max_func_cp_rings (bp );
178
192
msix_requested = edev -> ulp_tbl [ulp_id ].msix_requested ;
179
193
bnxt_set_max_func_cp_rings (bp , max_cp_rings + msix_requested );
180
194
edev -> ulp_tbl [ulp_id ].msix_requested = 0 ;
181
195
bnxt_set_max_func_irqs (bp , bnxt_get_max_func_irqs (bp ) + msix_requested );
196
+ edev -> flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED ;
182
197
if (netif_running (dev )) {
183
198
bnxt_close_nic (bp , true, false);
184
199
bnxt_open_nic (bp , true, false);
@@ -340,6 +355,58 @@ void bnxt_ulp_shutdown(struct bnxt *bp)
340
355
}
341
356
}
342
357
358
+ void bnxt_ulp_irq_stop (struct bnxt * bp )
359
+ {
360
+ struct bnxt_en_dev * edev = bp -> edev ;
361
+ struct bnxt_ulp_ops * ops ;
362
+
363
+ if (!edev || !(edev -> flags & BNXT_EN_FLAG_MSIX_REQUESTED ))
364
+ return ;
365
+
366
+ if (bnxt_ulp_registered (bp -> edev , BNXT_ROCE_ULP )) {
367
+ struct bnxt_ulp * ulp = & edev -> ulp_tbl [BNXT_ROCE_ULP ];
368
+
369
+ if (!ulp -> msix_requested )
370
+ return ;
371
+
372
+ ops = rtnl_dereference (ulp -> ulp_ops );
373
+ if (!ops || !ops -> ulp_irq_stop )
374
+ return ;
375
+ ops -> ulp_irq_stop (ulp -> handle );
376
+ }
377
+ }
378
+
379
+ void bnxt_ulp_irq_restart (struct bnxt * bp , int err )
380
+ {
381
+ struct bnxt_en_dev * edev = bp -> edev ;
382
+ struct bnxt_ulp_ops * ops ;
383
+
384
+ if (!edev || !(edev -> flags & BNXT_EN_FLAG_MSIX_REQUESTED ))
385
+ return ;
386
+
387
+ if (bnxt_ulp_registered (bp -> edev , BNXT_ROCE_ULP )) {
388
+ struct bnxt_ulp * ulp = & edev -> ulp_tbl [BNXT_ROCE_ULP ];
389
+ struct bnxt_msix_entry * ent = NULL ;
390
+
391
+ if (!ulp -> msix_requested )
392
+ return ;
393
+
394
+ ops = rtnl_dereference (ulp -> ulp_ops );
395
+ if (!ops || !ops -> ulp_irq_restart )
396
+ return ;
397
+
398
+ if (!err ) {
399
+ ent = kcalloc (ulp -> msix_requested , sizeof (* ent ),
400
+ GFP_KERNEL );
401
+ if (!ent )
402
+ return ;
403
+ bnxt_fill_msix_vecs (bp , ent );
404
+ }
405
+ ops -> ulp_irq_restart (ulp -> handle , ent );
406
+ kfree (ent );
407
+ }
408
+ }
409
+
343
410
void bnxt_ulp_async_events (struct bnxt * bp , struct hwrm_async_event_cmpl * cmpl )
344
411
{
345
412
u16 event_id = le16_to_cpu (cmpl -> event_id );
0 commit comments