Add layer to support Jailhouse hypervisor
[AGL/meta-agl-devel.git] / meta-agl-jailhouse / recipes-kernel / linux / linux / 0032-ivshmem-net-Adjust-to-reworked-version-of-ivshmem-in.patch
1 From 9caa6a8cab0d7f46475990aaeb7dcc7721547ef0 Mon Sep 17 00:00:00 2001
2 From: Jan Kiszka <jan.kiszka@siemens.com>
3 Date: Mon, 5 Dec 2016 15:43:53 +0100
4 Subject: [PATCH 32/32] ivshmem-net: Adjust to reworked version of ivshmem in
5  Jailhouse
6
7 This contains the changes required to work with the new revision of
8 ivshmem in Jailhouse, namely:
9
10 - changed PCI vendor and device ID
11 - vendor capability to communicate region location
12 - new MMIO register layout
13 - common interrupt control register
14 - state table support, removal of rstate register
15 - unidirectional shared memory regions
16 - vector value has to be written to doorbell register
17 - support for multiple vectors, used to split config from tx-rx
18
19 Note: Specification work for the interface is ongoing, so details may
20 still change.
21
22 Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
23 ---
24  drivers/net/ivshmem-net.c | 335 ++++++++++++++++++++++++++++++----------------
25  1 file changed, 223 insertions(+), 112 deletions(-)
26
27 diff --git a/drivers/net/ivshmem-net.c b/drivers/net/ivshmem-net.c
28 index 9946cef63c1f..18d5a15dbec2 100644
29 --- a/drivers/net/ivshmem-net.c
30 +++ b/drivers/net/ivshmem-net.c
31 @@ -1,5 +1,6 @@
32  /*
33   * Copyright 2016 Mans Rullgard <mans@mansr.com>
34 + * Copyright (c) Siemens AG, 2016-2020
35   *
36   * This program is free software; you can redistribute it and/or modify
37   * it under the terms of the GNU General Public License as published by
38 @@ -15,6 +16,7 @@
39   * along with this program; if not, see <http://www.gnu.org/licenses/>.
40   */
41  
42 +#include <linux/ivshmem.h>
43  #include <linux/kernel.h>
44  #include <linux/module.h>
45  #include <linux/pci.h>
46 @@ -28,34 +30,28 @@
47  
48  #define DRV_NAME "ivshmem-net"
49  
50 -#define JAILHOUSE_CFG_SHMEM_PTR        0x40
51 -#define JAILHOUSE_CFG_SHMEM_SZ 0x48
52 +#define IVSHM_NET_STATE_RESET          0
53 +#define IVSHM_NET_STATE_INIT           1
54 +#define IVSHM_NET_STATE_READY          2
55 +#define IVSHM_NET_STATE_RUN            3
56  
57 -#define IVSHMEM_INTX_ENABLE    0x1
58 +#define IVSHM_NET_FLAG_RUN             0
59  
60 -#define IVSHM_NET_STATE_RESET  0
61 -#define IVSHM_NET_STATE_INIT   1
62 -#define IVSHM_NET_STATE_READY  2
63 -#define IVSHM_NET_STATE_RUN    3
64 -
65 -#define IVSHM_NET_FLAG_RUN     0
66 -
67 -#define IVSHM_NET_MTU_MIN 256
68 -#define IVSHM_NET_MTU_MAX 65535
69 -#define IVSHM_NET_MTU_DEF 16384
70 +#define IVSHM_NET_MTU_MIN              256
71 +#define IVSHM_NET_MTU_MAX              65535
72 +#define IVSHM_NET_MTU_DEF              16384
73  
74  #define IVSHM_NET_FRAME_SIZE(s) ALIGN(18 + (s), SMP_CACHE_BYTES)
75  
76  #define IVSHM_NET_VQ_ALIGN 64
77  
78 -struct ivshmem_regs {
79 -       u32 intxctrl;
80 -       u32 istat;
81 -       u32 ivpos;
82 -       u32 doorbell;
83 -       u32 lstate;
84 -       u32 rstate;
85 -};
86 +#define IVSHM_NET_SECTION_TX           0
87 +#define IVSHM_NET_SECTION_RX           1
88 +
89 +#define IVSHM_NET_MSIX_STATE           0
90 +#define IVSHM_NET_MSIX_TX_RX           1
91 +
92 +#define IVSHM_NET_NUM_VECTORS          2
93  
94  struct ivshm_net_queue {
95         struct vring vr;
96 @@ -73,7 +69,7 @@ struct ivshm_net_queue {
97  };
98  
99  struct ivshm_net_stats {
100 -       u32 interrupts;
101 +       u32 tx_rx_interrupts;
102         u32 tx_packets;
103         u32 tx_notify;
104         u32 tx_pause;
105 @@ -97,8 +93,9 @@ struct ivshm_net {
106  
107         struct napi_struct napi;
108  
109 -       u32 lstate;
110 -       u32 rstate;
111 +       u32 state;
112 +       u32 last_peer_state;
113 +       u32 *state_table;
114  
115         unsigned long flags;
116  
117 @@ -107,17 +104,19 @@ struct ivshm_net {
118  
119         struct ivshm_net_stats stats;
120  
121 -       struct ivshmem_regs __iomem *ivshm_regs;
122 -       void *shm;
123 -       phys_addr_t shmaddr;
124 +       struct ivshm_regs __iomem *ivshm_regs;
125 +       void *shm[2];
126         resource_size_t shmlen;
127         u32 peer_id;
128  
129 +       u32 tx_rx_vector;
130 +
131         struct pci_dev *pdev;
132  };
133  
134  static void *ivshm_net_desc_data(struct ivshm_net *in,
135                                  struct ivshm_net_queue *q,
136 +                                unsigned int region,
137                                  struct vring_desc *desc,
138                                  u32 *len)
139  {
140 @@ -132,7 +131,7 @@ static void *ivshm_net_desc_data(struct ivshm_net *in,
141         if (offs >= in->shmlen)
142                 return NULL;
143  
144 -       data = in->shm + offs;
145 +       data = in->shm[region] + offs;
146  
147         if (data < q->data || data >= q->end)
148                 return NULL;
149 @@ -160,18 +159,17 @@ static void ivshm_net_init_queue(struct ivshm_net *in,
150  static void ivshm_net_init_queues(struct net_device *ndev)
151  {
152         struct ivshm_net *in = netdev_priv(ndev);
153 -       int ivpos = readl(&in->ivshm_regs->ivpos);
154         void *tx;
155         void *rx;
156         int i;
157  
158 -       tx = in->shm +  ivpos * in->shmlen / 2;
159 -       rx = in->shm + !ivpos * in->shmlen / 2;
160 +       tx = in->shm[IVSHM_NET_SECTION_TX];
161 +       rx = in->shm[IVSHM_NET_SECTION_RX];
162  
163 -       memset(tx, 0, in->shmlen / 2);
164 +       memset(tx, 0, in->shmlen);
165  
166 -       ivshm_net_init_queue(in, &in->rx, rx, in->qlen);
167         ivshm_net_init_queue(in, &in->tx, tx, in->qlen);
168 +       ivshm_net_init_queue(in, &in->rx, rx, in->qlen);
169  
170         swap(in->rx.vr.used, in->tx.vr.used);
171  
172 @@ -191,14 +189,14 @@ static int ivshm_net_calc_qsize(struct net_device *ndev)
173         for (qlen = 4096; qlen > 32; qlen >>= 1) {
174                 vrsize = vring_size(qlen, IVSHM_NET_VQ_ALIGN);
175                 vrsize = ALIGN(vrsize, IVSHM_NET_VQ_ALIGN);
176 -               if (vrsize < in->shmlen / 16)
177 +               if (vrsize < in->shmlen / 8)
178                         break;
179         }
180  
181 -       if (vrsize > in->shmlen / 2)
182 +       if (vrsize > in->shmlen)
183                 return -EINVAL;
184  
185 -       qsize = in->shmlen / 2 - vrsize;
186 +       qsize = in->shmlen - vrsize;
187  
188         if (qsize < 4 * IVSHM_NET_MTU_MIN)
189                 return -EINVAL;
190 @@ -221,7 +219,8 @@ static void ivshm_net_notify_tx(struct ivshm_net *in, unsigned int num)
191         new = in->tx.last_avail_idx;
192  
193         if (vring_need_event(evt, new, old)) {
194 -               writel(in->peer_id << 16, &in->ivshm_regs->doorbell);
195 +               writel(in->tx_rx_vector | (in->peer_id << 16),
196 +                      &in->ivshm_regs->doorbell);
197                 in->stats.tx_notify++;
198         }
199  }
200 @@ -243,7 +242,8 @@ static void ivshm_net_notify_rx(struct ivshm_net *in, unsigned int num)
201         new = in->rx.last_used_idx;
202  
203         if (vring_need_event(evt, new, old)) {
204 -               writel(in->peer_id << 16, &in->ivshm_regs->doorbell);
205 +               writel(in->tx_rx_vector | (in->peer_id << 16),
206 +                      &in->ivshm_regs->doorbell);
207                 in->stats.rx_notify++;
208         }
209  }
210 @@ -320,7 +320,7 @@ static int ivshm_net_tx_frame(struct net_device *ndev, struct sk_buff *skb,
211         buf = tx->data + head;
212         skb_copy_and_csum_dev(skb, buf);
213  
214 -       desc->addr = buf - in->shm;
215 +       desc->addr = buf - in->shm[IVSHM_NET_SECTION_TX];
216         desc->len = skb->len;
217         desc->flags = 0;
218  
219 @@ -374,7 +374,8 @@ static void ivshm_net_tx_clean(struct net_device *ndev)
220  
221                 desc = &vr->desc[used->id];
222  
223 -               data = ivshm_net_desc_data(in, &in->tx, desc, &len);
224 +               data = ivshm_net_desc_data(in, &in->tx, IVSHM_NET_SECTION_TX,
225 +                                          desc, &len);
226                 if (!data) {
227                         netdev_err(ndev, "bad tx descriptor, data == NULL\n");
228                         break;
229 @@ -466,7 +467,8 @@ static int ivshm_net_poll(struct napi_struct *napi, int budget)
230                 if (!desc)
231                         break;
232  
233 -               data = ivshm_net_desc_data(in, &in->rx, desc, &len);
234 +               data = ivshm_net_desc_data(in, &in->rx, IVSHM_NET_SECTION_RX,
235 +                                          desc, &len);
236                 if (!data) {
237                         netdev_err(ndev, "bad rx descriptor\n");
238                         break;
239 @@ -535,15 +537,15 @@ static netdev_tx_t ivshm_net_xmit(struct sk_buff *skb, struct net_device *ndev)
240  static void ivshm_net_set_state(struct ivshm_net *in, u32 state)
241  {
242         virt_wmb();
243 -       WRITE_ONCE(in->lstate, state);
244 -       writel(state, &in->ivshm_regs->lstate);
245 +       WRITE_ONCE(in->state, state);
246 +       writel(state, &in->ivshm_regs->state);
247  }
248  
249  static void ivshm_net_run(struct net_device *ndev)
250  {
251         struct ivshm_net *in = netdev_priv(ndev);
252  
253 -       if (in->lstate < IVSHM_NET_STATE_READY)
254 +       if (in->state < IVSHM_NET_STATE_READY)
255                 return;
256  
257         if (!netif_running(ndev))
258 @@ -575,15 +577,15 @@ static void ivshm_net_state_change(struct work_struct *work)
259  {
260         struct ivshm_net *in = container_of(work, struct ivshm_net, state_work);
261         struct net_device *ndev = in->napi.dev;
262 -       u32 rstate = readl(&in->ivshm_regs->rstate);
263 +       u32 peer_state = READ_ONCE(in->state_table[in->peer_id]);
264  
265 -       switch (in->lstate) {
266 +       switch (in->state) {
267         case IVSHM_NET_STATE_RESET:
268                 /*
269                  * Wait for the remote to leave READY/RUN before transitioning
270                  * to INIT.
271                  */
272 -               if (rstate < IVSHM_NET_STATE_READY)
273 +               if (peer_state < IVSHM_NET_STATE_READY)
274                         ivshm_net_set_state(in, IVSHM_NET_STATE_INIT);
275                 break;
276  
277 @@ -592,7 +594,7 @@ static void ivshm_net_state_change(struct work_struct *work)
278                  * Wait for the remote to leave RESET before performing the
279                  * initialization and moving to READY.
280                  */
281 -               if (rstate > IVSHM_NET_STATE_RESET) {
282 +               if (peer_state > IVSHM_NET_STATE_RESET) {
283                         ivshm_net_init_queues(ndev);
284                         ivshm_net_set_state(in, IVSHM_NET_STATE_READY);
285  
286 @@ -607,7 +609,7 @@ static void ivshm_net_state_change(struct work_struct *work)
287                  * Link is up and we are running once the remote is in READY or
288                  * RUN.
289                  */
290 -               if (rstate >= IVSHM_NET_STATE_READY) {
291 +               if (peer_state >= IVSHM_NET_STATE_READY) {
292                         netif_carrier_on(ndev);
293                         ivshm_net_run(ndev);
294                         break;
295 @@ -617,7 +619,7 @@ static void ivshm_net_state_change(struct work_struct *work)
296                 /*
297                  * If the remote goes to RESET, we need to follow immediately.
298                  */
299 -               if (rstate == IVSHM_NET_STATE_RESET) {
300 +               if (peer_state == IVSHM_NET_STATE_RESET) {
301                         netif_carrier_off(ndev);
302                         ivshm_net_do_stop(ndev);
303                 }
304 @@ -625,31 +627,44 @@ static void ivshm_net_state_change(struct work_struct *work)
305         }
306  
307         virt_wmb();
308 -       WRITE_ONCE(in->rstate, rstate);
309 +       WRITE_ONCE(in->last_peer_state, peer_state);
310  }
311  
312 -static void ivshm_net_check_state(struct net_device *ndev)
313 +static void ivshm_net_check_state(struct ivshm_net *in)
314  {
315 -       struct ivshm_net *in = netdev_priv(ndev);
316 -       u32 rstate = readl(&in->ivshm_regs->rstate);
317 -
318 -       if (rstate != in->rstate || !test_bit(IVSHM_NET_FLAG_RUN, &in->flags))
319 +       if (in->state_table[in->peer_id] != in->last_peer_state ||
320 +           !test_bit(IVSHM_NET_FLAG_RUN, &in->flags))
321                 queue_work(in->state_wq, &in->state_work);
322  }
323  
324 -static irqreturn_t ivshm_net_int(int irq, void *data)
325 +static irqreturn_t ivshm_net_int_state(int irq, void *data)
326  {
327 -       struct net_device *ndev = data;
328 -       struct ivshm_net *in = netdev_priv(ndev);
329 +       struct ivshm_net *in = data;
330 +
331 +       ivshm_net_check_state(in);
332 +
333 +       return IRQ_HANDLED;
334 +}
335  
336 -       in->stats.interrupts++;
337 +static irqreturn_t ivshm_net_int_tx_rx(int irq, void *data)
338 +{
339 +       struct ivshm_net *in = data;
340 +
341 +       in->stats.tx_rx_interrupts++;
342  
343 -       ivshm_net_check_state(ndev);
344         napi_schedule_irqoff(&in->napi);
345  
346         return IRQ_HANDLED;
347  }
348  
349 +static irqreturn_t ivshm_net_intx(int irq, void *data)
350 +{
351 +       ivshm_net_int_state(irq, data);
352 +       ivshm_net_int_tx_rx(irq, data);
353 +
354 +       return IRQ_HANDLED;
355 +}
356 +
357  static int ivshm_net_open(struct net_device *ndev)
358  {
359         netdev_reset_queue(ndev);
360 @@ -717,7 +732,7 @@ static const struct net_device_ops ivshm_net_ops = {
361  };
362  
363  static const char ivshm_net_stats[][ETH_GSTRING_LEN] = {
364 -       "interrupts",
365 +       "tx_rx_interrupts",
366         "tx_packets",
367         "tx_notify",
368         "tx_pause",
369 @@ -760,7 +775,7 @@ static void ivshm_net_get_ethtool_stats(struct net_device *ndev,
370         unsigned int n = 0;
371         unsigned int i;
372  
373 -       st[n++] = in->stats.interrupts;
374 +       st[n++] = in->stats.tx_rx_interrupts;
375         st[n++] = in->stats.tx_packets;
376         st[n++] = in->stats.tx_notify;
377         st[n++] = in->stats.tx_pause;
378 @@ -789,8 +804,8 @@ static void ivshm_net_get_regs(struct net_device *ndev,
379         u32 *reg32 = p;
380         u16 *reg16;
381  
382 -       *reg32++ = in->lstate;
383 -       *reg32++ = in->rstate;
384 +       *reg32++ = in->state;
385 +       *reg32++ = in->last_peer_state;
386         *reg32++ = in->qlen;
387  
388         reg16 = (u16 *)reg32;
389 @@ -812,17 +827,28 @@ static const struct ethtool_ops ivshm_net_ethtool_ops = {
390         .get_regs               = ivshm_net_get_regs,
391  };
392  
393 +static u64 get_config_qword(struct pci_dev *pdev, unsigned int pos)
394 +{
395 +       u32 lo, hi;
396 +
397 +       pci_read_config_dword(pdev, pos, &lo);
398 +       pci_read_config_dword(pdev, pos + 4, &hi);
399 +       return lo | ((u64)hi << 32);
400 +}
401 +
402  static int ivshm_net_probe(struct pci_dev *pdev,
403 -                          const struct pci_device_id *id)
404 +                          const struct pci_device_id *pci_id)
405  {
406 +       phys_addr_t output_sections_addr, section_addr;
407 +       resource_size_t section_sz, output_section_sz;
408 +       void *state_table, *output_sections;
409 +       struct ivshm_regs __iomem *regs;
410         struct net_device *ndev;
411         struct ivshm_net *in;
412 -       struct ivshmem_regs __iomem *regs;
413 -       resource_size_t shmaddr;
414 -       resource_size_t shmlen;
415 +       unsigned int cap_pos;
416         char *device_name;
417 -       void *shm;
418 -       u32 ivpos;
419 +       int vendor_cap;
420 +       u32 id, dword;
421         int ret;
422  
423         ret = pcim_enable_device(pdev);
424 @@ -839,40 +865,75 @@ static int ivshm_net_probe(struct pci_dev *pdev,
425  
426         regs = pcim_iomap_table(pdev)[0];
427  
428 -       shmlen = pci_resource_len(pdev, 2);
429 +       id = readl(&regs->id);
430 +       if (id > 1) {
431 +               dev_err(&pdev->dev, "invalid ID %d\n", id);
432 +               return -EINVAL;
433 +       }
434 +       if (readl(&regs->max_peers) > 2) {
435 +               dev_err(&pdev->dev, "only 2 peers supported\n");
436 +               return -EINVAL;
437 +       }
438 +
439 +       vendor_cap = pci_find_capability(pdev, PCI_CAP_ID_VNDR);
440 +       if (vendor_cap < 0) {
441 +               dev_err(&pdev->dev, "missing vendor capability\n");
442 +               return -EINVAL;
443 +       }
444  
445 -       if (shmlen) {
446 -               shmaddr = pci_resource_start(pdev, 2);
447 +       if (pci_resource_len(pdev, 2) > 0) {
448 +               section_addr = pci_resource_start(pdev, 2);
449         } else {
450 -               union { u64 v; u32 hl[2]; } val;
451 -
452 -               pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_PTR,
453 -                                     &val.hl[0]);
454 -               pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_PTR + 4,
455 -                                     &val.hl[1]);
456 -               shmaddr = val.v;
457 -
458 -               pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_SZ,
459 -                                     &val.hl[0]);
460 -               pci_read_config_dword(pdev, JAILHOUSE_CFG_SHMEM_SZ + 4,
461 -                                     &val.hl[1]);
462 -               shmlen = val.v;
463 +               cap_pos = vendor_cap + IVSHM_CFG_ADDRESS;
464 +               section_addr = get_config_qword(pdev, cap_pos);
465         }
466  
467 +       cap_pos = vendor_cap + IVSHM_CFG_STATE_TAB_SZ;
468 +       pci_read_config_dword(pdev, cap_pos, &dword);
469 +       section_sz = dword;
470  
471 -       if (!devm_request_mem_region(&pdev->dev, shmaddr, shmlen, DRV_NAME))
472 +       if (!devm_request_mem_region(&pdev->dev, section_addr, section_sz,
473 +                                    DRV_NAME))
474                 return -EBUSY;
475  
476 -       shm = devm_memremap(&pdev->dev, shmaddr, shmlen, MEMREMAP_WB);
477 -       if (!shm)
478 +       state_table = devm_memremap(&pdev->dev, section_addr, section_sz,
479 +                                   MEMREMAP_WB);
480 +       if (!state_table)
481                 return -ENOMEM;
482  
483 -       ivpos = readl(&regs->ivpos);
484 -       if (ivpos > 1) {
485 -               dev_err(&pdev->dev, "invalid IVPosition %d\n", ivpos);
486 +       output_sections_addr = section_addr + section_sz;
487 +
488 +       cap_pos = vendor_cap + IVSHM_CFG_RW_SECTION_SZ;
489 +       section_sz = get_config_qword(pdev, cap_pos);
490 +       if (section_sz > 0) {
491 +               dev_info(&pdev->dev, "R/W section detected - "
492 +                        "unused by this driver version\n");
493 +               output_sections_addr += section_sz;
494 +       }
495 +
496 +       cap_pos = vendor_cap + IVSHM_CFG_OUTPUT_SECTION_SZ;
497 +       output_section_sz = get_config_qword(pdev, cap_pos);
498 +       if (output_section_sz == 0) {
499 +               dev_err(&pdev->dev, "Missing input/output sections\n");
500                 return -EINVAL;
501         }
502  
503 +       if (!devm_request_mem_region(&pdev->dev, output_sections_addr,
504 +                                    output_section_sz * 2, DRV_NAME))
505 +               return -EBUSY;
506 +
507 +       output_sections = devm_memremap(&pdev->dev, output_sections_addr,
508 +                                       output_section_sz * 2, MEMREMAP_WB);
509 +       if (!output_sections)
510 +               return -ENOMEM;
511 +
512 +       section_addr = output_sections_addr + output_section_sz * id;
513 +       dev_info(&pdev->dev, "TX memory at %pa, size %pa\n",
514 +                &section_addr, &output_section_sz);
515 +       section_addr = output_sections_addr + output_section_sz * !id;
516 +       dev_info(&pdev->dev, "RX memory at %pa, size %pa\n",
517 +                &section_addr, &output_section_sz);
518 +
519         device_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s[%s]", DRV_NAME,
520                                      dev_name(&pdev->dev));
521         if (!device_name)
522 @@ -887,10 +948,16 @@ static int ivshm_net_probe(struct pci_dev *pdev,
523  
524         in = netdev_priv(ndev);
525         in->ivshm_regs = regs;
526 -       in->shm = shm;
527 -       in->shmaddr = shmaddr;
528 -       in->shmlen = shmlen;
529 -       in->peer_id = !ivpos;
530 +       in->state_table = state_table;
531 +
532 +       in->shm[IVSHM_NET_SECTION_TX] =
533 +               output_sections + output_section_sz * id;
534 +       in->shm[IVSHM_NET_SECTION_RX] =
535 +               output_sections + output_section_sz * !id;
536 +
537 +       in->shmlen = output_section_sz;
538 +
539 +       in->peer_id = !id;
540         in->pdev = pdev;
541         spin_lock_init(&in->tx_free_lock);
542         spin_lock_init(&in->tx_clean_lock);
543 @@ -919,24 +986,64 @@ static int ivshm_net_probe(struct pci_dev *pdev,
544         if (ret)
545                 goto err_wq;
546  
547 -       ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY | PCI_IRQ_MSIX);
548 +       ret = pci_alloc_irq_vectors(pdev, 1, 2, PCI_IRQ_LEGACY | PCI_IRQ_MSIX);
549         if (ret < 0)
550                 goto err_alloc_irq;
551  
552 -       ret = request_irq(pci_irq_vector(pdev, 0), ivshm_net_int, 0,
553 -                         device_name, ndev);
554 -       if (ret)
555 -               goto err_request_irq;
556 +       if (pdev->msix_enabled) {
557 +               if (ret != 2) {
558 +                       ret = -EBUSY;
559 +                       goto err_request_irq;
560 +               }
561 +
562 +               device_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
563 +                                            "%s-state[%s]", DRV_NAME,
564 +                                            dev_name(&pdev->dev));
565 +               if (!device_name) {
566 +                       ret = -ENOMEM;
567 +                       goto err_request_irq;
568 +               }
569 +
570 +               ret = request_irq(pci_irq_vector(pdev, IVSHM_NET_MSIX_STATE),
571 +                                 ivshm_net_int_state, 0, device_name, in);
572 +               if (ret)
573 +                       goto err_request_irq;
574 +
575 +               device_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
576 +                                            "%s-tx-rx[%s]", DRV_NAME,
577 +                                            dev_name(&pdev->dev));
578 +               if (!device_name) {
579 +                       ret = -ENOMEM;
580 +                       goto err_request_irq2;
581 +               }
582 +
583 +               ret = request_irq(pci_irq_vector(pdev, IVSHM_NET_MSIX_TX_RX),
584 +                                 ivshm_net_int_tx_rx, 0, device_name, in);
585 +               if (ret)
586 +                       goto err_request_irq2;
587 +
588 +               in->tx_rx_vector = IVSHM_NET_MSIX_TX_RX;
589 +       } else {
590 +               ret = request_irq(pci_irq_vector(pdev, 0), ivshm_net_intx, 0,
591 +                                 device_name, in);
592 +               if (ret)
593 +                       goto err_request_irq;
594 +
595 +               in->tx_rx_vector = 0;
596 +       }
597  
598         pci_set_master(pdev);
599 -       if (!pdev->msix_enabled)
600 -               writel(IVSHMEM_INTX_ENABLE, &in->ivshm_regs->intxctrl);
601  
602 -       writel(IVSHM_NET_STATE_RESET, &in->ivshm_regs->lstate);
603 -       ivshm_net_check_state(ndev);
604 +       pci_write_config_byte(pdev, vendor_cap + IVSHM_CFG_PRIV_CNTL, 0);
605 +       writel(IVSHM_INT_ENABLE, &in->ivshm_regs->int_control);
606 +
607 +       writel(IVSHM_NET_STATE_RESET, &in->ivshm_regs->state);
608 +       ivshm_net_check_state(in);
609  
610         return 0;
611  
612 +err_request_irq2:
613 +       free_irq(pci_irq_vector(pdev, IVSHM_NET_MSIX_STATE), in);
614  err_request_irq:
615         pci_free_irq_vectors(pdev);
616  err_alloc_irq:
617 @@ -954,11 +1061,15 @@ static void ivshm_net_remove(struct pci_dev *pdev)
618         struct net_device *ndev = pci_get_drvdata(pdev);
619         struct ivshm_net *in = netdev_priv(ndev);
620  
621 -       writel(IVSHM_NET_STATE_RESET, &in->ivshm_regs->lstate);
622 +       writel(IVSHM_NET_STATE_RESET, &in->ivshm_regs->state);
623 +       writel(0, &in->ivshm_regs->int_control);
624  
625 -       if (!pdev->msix_enabled)
626 -               writel(0, &in->ivshm_regs->intxctrl);
627 -       free_irq(pci_irq_vector(pdev, 0), ndev);
628 +       if (pdev->msix_enabled) {
629 +               free_irq(pci_irq_vector(pdev, IVSHM_NET_MSIX_STATE), in);
630 +               free_irq(pci_irq_vector(pdev, IVSHM_NET_MSIX_TX_RX), in);
631 +       } else {
632 +               free_irq(pci_irq_vector(pdev, 0), in);
633 +       }
634         pci_free_irq_vectors(pdev);
635  
636         unregister_netdev(ndev);
637 @@ -968,8 +1079,8 @@ static void ivshm_net_remove(struct pci_dev *pdev)
638  }
639  
640  static const struct pci_device_id ivshm_net_id_table[] = {
641 -       { PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, 0x1110),
642 -               (PCI_CLASS_OTHERS << 16) | (0x01 << 8), 0xffff00 },
643 +       { PCI_DEVICE(PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_IVSHMEM),
644 +         (PCI_CLASS_OTHERS << 16) | IVSHM_PROTO_NET, 0xffffff },
645         { 0 }
646  };
647  MODULE_DEVICE_TABLE(pci, ivshm_net_id_table);
648 -- 
649 2.11.0
650