vFW: changes for gateway packet forwarding
[samplevnf.git] / patches / dpdk_custom_patch / i40e-fix-VF-bonded-device-link-down.patch
1 diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
2 index 9c1f542..13060db 100644
3 --- a/drivers/net/i40e/i40e_ethdev.c
4 +++ b/drivers/net/i40e/i40e_ethdev.c
5 @@ -5418,6 +5418,24 @@ i40e_dev_handle_vfr_event(struct rte_eth_dev *dev)
6  }
7  
8  static void
9 +i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev)
10 +{
11 +       struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
12 +       struct i40e_virtchnl_pf_event event;
13 +       int i;
14 +
15 +       event.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
16 +       event.event_data.link_event.link_status =
17 +               dev->data->dev_link.link_status;
18 +       event.event_data.link_event.link_speed =
19 +               dev->data->dev_link.link_speed;
20 +
21 +       for (i = 0; i < pf->vf_num; i++)
22 +               i40e_pf_host_send_msg_to_vf(&pf->vfs[i], I40E_VIRTCHNL_OP_EVENT,
23 +                               I40E_SUCCESS, (uint8_t *)&event, sizeof(event));
24 +}
25 +
26 +static void
27  i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
28  {
29         struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
30 @@ -5455,9 +5473,11 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
31                         break;
32                 case i40e_aqc_opc_get_link_status:
33                         ret = i40e_dev_link_update(dev, 0);
34 -                       if (!ret)
35 +                       if (!ret) {
36 +                               i40e_notify_all_vfs_link_status(dev);
37                                 _rte_eth_dev_callback_process(dev,
38                                         RTE_ETH_EVENT_INTR_LSC);
39 +                       }
40                         break;
41                 default:
42                         PMD_DRV_LOG(ERR, "Request %u is not supported yet",
43 diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
44 index 92c8fad..61dfa93 100644
45 --- a/drivers/net/i40e/i40e_ethdev.h
46 +++ b/drivers/net/i40e/i40e_ethdev.h
47 @@ -599,7 +599,9 @@ int i40e_hash_filter_inset_select(struct i40e_hw *hw,
48                              struct rte_eth_input_set_conf *conf);
49  int i40e_fdir_filter_inset_select(struct i40e_pf *pf,
50                              struct rte_eth_input_set_conf *conf);
51 -
52 +int i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf, uint32_t opcode,
53 +                               uint32_t retval, uint8_t *msg,
54 +                               uint16_t msglen);
55  void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
56         struct rte_eth_rxq_info *qinfo);
57  void i40e_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
58 diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
59 index a616ae0..ba63a7f 100644
60 --- a/drivers/net/i40e/i40e_ethdev_vf.c
61 +++ b/drivers/net/i40e/i40e_ethdev_vf.c
62 @@ -126,8 +126,6 @@ static void i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev);
63  static void i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev);
64  static void i40evf_dev_allmulticast_enable(struct rte_eth_dev *dev);
65  static void i40evf_dev_allmulticast_disable(struct rte_eth_dev *dev);
66 -static int i40evf_get_link_status(struct rte_eth_dev *dev,
67 -                                 struct rte_eth_link *link);
68  static int i40evf_init_vlan(struct rte_eth_dev *dev);
69  static int i40evf_dev_rx_queue_start(struct rte_eth_dev *dev,
70                                      uint16_t rx_queue_id);
71 @@ -1084,31 +1082,6 @@ i40evf_del_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
72         return err;
73  }
74  
75 -static int
76 -i40evf_get_link_status(struct rte_eth_dev *dev, struct rte_eth_link *link)
77 -{
78 -       struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
79 -       int err;
80 -       struct vf_cmd_info args;
81 -       struct rte_eth_link *new_link;
82 -
83 -       args.ops = (enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_GET_LINK_STAT;
84 -       args.in_args = NULL;
85 -       args.in_args_size = 0;
86 -       args.out_buffer = vf->aq_resp;
87 -       args.out_size = I40E_AQ_BUF_SZ;
88 -       err = i40evf_execute_vf_cmd(dev, &args);
89 -       if (err) {
90 -               PMD_DRV_LOG(ERR, "fail to execute command OP_GET_LINK_STAT");
91 -               return err;
92 -       }
93 -
94 -       new_link = (struct rte_eth_link *)args.out_buffer;
95 -       (void)rte_memcpy(link, new_link, sizeof(*link));
96 -
97 -       return 0;
98 -}
99 -
100  static const struct rte_pci_id pci_id_i40evf_map[] = {
101         { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_VF) },
102         { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_VF_HV) },
103 @@ -2166,35 +2139,33 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
104          * DPDK pf host provide interfacet to acquire link status
105          * while Linux driver does not
106          */
107 -       if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
108 -               i40evf_get_link_status(dev, &new_link);
109 -       else {
110 -               /* Linux driver PF host */
111 -               switch (vf->link_speed) {
112 -               case I40E_LINK_SPEED_100MB:
113 -                       new_link.link_speed = ETH_SPEED_NUM_100M;
114 -                       break;
115 -               case I40E_LINK_SPEED_1GB:
116 -                       new_link.link_speed = ETH_SPEED_NUM_1G;
117 -                       break;
118 -               case I40E_LINK_SPEED_10GB:
119 -                       new_link.link_speed = ETH_SPEED_NUM_10G;
120 -                       break;
121 -               case I40E_LINK_SPEED_20GB:
122 -                       new_link.link_speed = ETH_SPEED_NUM_20G;
123 -                       break;
124 -               case I40E_LINK_SPEED_40GB:
125 -                       new_link.link_speed = ETH_SPEED_NUM_40G;
126 -                       break;
127 -               default:
128 -                       new_link.link_speed = ETH_SPEED_NUM_100M;
129 -                       break;
130 -               }
131 -               /* full duplex only */
132 -               new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
133 -               new_link.link_status = vf->link_up ? ETH_LINK_UP :
134 -                                                    ETH_LINK_DOWN;
135 +
136 +       /* Linux driver PF host */
137 +       switch (vf->link_speed) {
138 +       case I40E_LINK_SPEED_100MB:
139 +               new_link.link_speed = ETH_SPEED_NUM_100M;
140 +               break;
141 +       case I40E_LINK_SPEED_1GB:
142 +               new_link.link_speed = ETH_SPEED_NUM_1G;
143 +               break;
144 +       case I40E_LINK_SPEED_10GB:
145 +               new_link.link_speed = ETH_SPEED_NUM_10G;
146 +               break;
147 +       case I40E_LINK_SPEED_20GB:
148 +               new_link.link_speed = ETH_SPEED_NUM_20G;
149 +               break;
150 +       case I40E_LINK_SPEED_40GB:
151 +               new_link.link_speed = ETH_SPEED_NUM_40G;
152 +               break;
153 +       default:
154 +               new_link.link_speed = ETH_SPEED_NUM_100M;
155 +               break;
156         }
157 +       /* full duplex only */
158 +       new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
159 +       new_link.link_status = vf->link_up ? ETH_LINK_UP :
160 +                                            ETH_LINK_DOWN;
161 +
162         i40evf_dev_atomic_write_link_status(dev, &new_link);
163  
164         return 0;
165 diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
166 index d5b2d45..350f6a0 100644
167 --- a/drivers/net/i40e/i40e_pf.c
168 +++ b/drivers/net/i40e/i40e_pf.c
169 @@ -250,7 +250,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset)
170         return ret;
171  }
172  
173 -static int
174 +int
175  i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf,
176                             uint32_t opcode,
177                             uint32_t retval,
178 @@ -847,18 +847,6 @@ i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf)
179         return I40E_SUCCESS;
180  }
181  
182 -static void
183 -i40e_pf_host_process_cmd_get_link_status(struct i40e_pf_vf *vf)
184 -{
185 -       struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vf->pf->main_vsi);
186 -
187 -       /* Update link status first to acquire latest link change */
188 -       i40e_dev_link_update(dev, 1);
189 -       i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_LINK_STAT,
190 -               I40E_SUCCESS, (uint8_t *)&dev->data->dev_link,
191 -                               sizeof(struct rte_eth_link));
192 -}
193 -
194  static int
195  i40e_pf_host_process_cmd_cfg_vlan_offload(
196                                         struct i40e_pf_vf *vf,
197 @@ -909,6 +897,20 @@ send_msg:
198         return ret;
199  }
200  
201 +static void
202 +i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf)
203 +{
204 +       struct i40e_virtchnl_pf_event event;
205 +
206 +       event.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
207 +       event.event_data.link_event.link_status =
208 +                       dev->data->dev_link.link_status;
209 +       event.event_data.link_event.link_speed =
210 +                       dev->data->dev_link.link_speed;
211 +       i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_EVENT,
212 +                       I40E_SUCCESS, (uint8_t *)&event, sizeof(event));
213 +}
214 +
215  void
216  i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
217                            uint16_t abs_vf_id, uint32_t opcode,
218 @@ -964,6 +966,7 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
219         case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
220                 PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received");
221                 i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen);
222 +               i40e_notify_vf_link_status(dev, vf);
223                 break;
224         case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
225                 PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received");
226 @@ -993,10 +996,6 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
227                 PMD_DRV_LOG(INFO, "OP_GET_STATS received");
228                 i40e_pf_host_process_cmd_get_stats(vf);
229                 break;
230 -       case I40E_VIRTCHNL_OP_GET_LINK_STAT:
231 -               PMD_DRV_LOG(INFO, "OP_GET_LINK_STAT received");
232 -               i40e_pf_host_process_cmd_get_link_status(vf);
233 -               break;
234         case I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD:
235                 PMD_DRV_LOG(INFO, "OP_CFG_VLAN_OFFLOAD received");
236                 i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg, msglen);
237 diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h
238 index 9c01829..cddc45c 100644
239 --- a/drivers/net/i40e/i40e_pf.h
240 +++ b/drivers/net/i40e/i40e_pf.h
241 @@ -59,9 +59,8 @@ enum i40e_virtchnl_ops_dpdk {
242          * Keep some gap between Linux PF commands and
243          * DPDK PF extended commands.
244          */
245 -       I40E_VIRTCHNL_OP_GET_LINK_STAT = I40E_VIRTCHNL_OP_VERSION +
246 +       I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD = I40E_VIRTCHNL_OP_VERSION +
247                                                 I40E_DPDK_OFFSET,
248 -       I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD,
249         I40E_VIRTCHNL_OP_CFG_VLAN_PVID,
250         I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT,
251  };