diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-10-27 19:46:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-28 06:25:39 -0400 |
commit | f2ca0dbe077389f061ffa15de9dd7fc96a5b97d2 (patch) | |
tree | b8b2b8e7c4d7bb7d65597c2fd60e65d5aec3b8bd | |
parent | d249be54745259980dcbd898bdfeb7307c9c5e10 (diff) |
igb: replace the VF clear_to_send with a flags value
In order to support future features it is easiest to replace the
clear_to_send boolean with a flag value.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/igb/igb.h | 5 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 125 |
2 files changed, 70 insertions, 60 deletions
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 1a0ae57dcee3..7801d3f40193 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h | |||
@@ -73,9 +73,12 @@ struct vf_data_storage { | |||
73 | u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES]; | 73 | u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES]; |
74 | u16 num_vf_mc_hashes; | 74 | u16 num_vf_mc_hashes; |
75 | u16 vlans_enabled; | 75 | u16 vlans_enabled; |
76 | bool clear_to_send; | 76 | u32 flags; |
77 | unsigned long last_nack; | ||
77 | }; | 78 | }; |
78 | 79 | ||
80 | #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ | ||
81 | |||
79 | /* RX descriptor control thresholds. | 82 | /* RX descriptor control thresholds. |
80 | * PTHRESH - MAC will consider prefetch if it has fewer than this number of | 83 | * PTHRESH - MAC will consider prefetch if it has fewer than this number of |
81 | * descriptors available in its onboard memory. | 84 | * descriptors available in its onboard memory. |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 2ed2694df5ab..a9e8ba244001 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -125,9 +125,8 @@ static void igb_restore_vlan(struct igb_adapter *); | |||
125 | static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8); | 125 | static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8); |
126 | static void igb_ping_all_vfs(struct igb_adapter *); | 126 | static void igb_ping_all_vfs(struct igb_adapter *); |
127 | static void igb_msg_task(struct igb_adapter *); | 127 | static void igb_msg_task(struct igb_adapter *); |
128 | static int igb_rcv_msg_from_vf(struct igb_adapter *, u32); | ||
129 | static void igb_vmm_control(struct igb_adapter *); | 128 | static void igb_vmm_control(struct igb_adapter *); |
130 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); | 129 | static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *); |
131 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); | 130 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); |
132 | 131 | ||
133 | static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn) | 132 | static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn) |
@@ -1291,10 +1290,10 @@ void igb_reset(struct igb_adapter *adapter) | |||
1291 | if (adapter->vfs_allocated_count) { | 1290 | if (adapter->vfs_allocated_count) { |
1292 | int i; | 1291 | int i; |
1293 | for (i = 0 ; i < adapter->vfs_allocated_count; i++) | 1292 | for (i = 0 ; i < adapter->vfs_allocated_count; i++) |
1294 | adapter->vf_data[i].clear_to_send = false; | 1293 | adapter->vf_data[i].flags = 0; |
1295 | 1294 | ||
1296 | /* ping all the active vfs to let them know we are going down */ | 1295 | /* ping all the active vfs to let them know we are going down */ |
1297 | igb_ping_all_vfs(adapter); | 1296 | igb_ping_all_vfs(adapter); |
1298 | 1297 | ||
1299 | /* disable transmits and receives */ | 1298 | /* disable transmits and receives */ |
1300 | wr32(E1000_VFRE, 0); | 1299 | wr32(E1000_VFRE, 0); |
@@ -4096,7 +4095,7 @@ static void igb_ping_all_vfs(struct igb_adapter *adapter) | |||
4096 | 4095 | ||
4097 | for (i = 0 ; i < adapter->vfs_allocated_count; i++) { | 4096 | for (i = 0 ; i < adapter->vfs_allocated_count; i++) { |
4098 | ping = E1000_PF_CONTROL_MSG; | 4097 | ping = E1000_PF_CONTROL_MSG; |
4099 | if (adapter->vf_data[i].clear_to_send) | 4098 | if (adapter->vf_data[i].flags & IGB_VF_FLAG_CTS) |
4100 | ping |= E1000_VT_MSGTYPE_CTS; | 4099 | ping |= E1000_VT_MSGTYPE_CTS; |
4101 | igb_write_mbx(hw, &ping, 1, i); | 4100 | igb_write_mbx(hw, &ping, 1, i); |
4102 | } | 4101 | } |
@@ -4276,15 +4275,14 @@ static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) | |||
4276 | return igb_vlvf_set(adapter, vid, add, vf); | 4275 | return igb_vlvf_set(adapter, vid, add, vf); |
4277 | } | 4276 | } |
4278 | 4277 | ||
4279 | static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf) | 4278 | static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf) |
4280 | { | 4279 | { |
4281 | struct e1000_hw *hw = &adapter->hw; | 4280 | /* clear all flags */ |
4282 | 4281 | adapter->vf_data[vf].flags = 0; | |
4283 | /* disable mailbox functionality for vf */ | 4282 | adapter->vf_data[vf].last_nack = jiffies; |
4284 | adapter->vf_data[vf].clear_to_send = false; | ||
4285 | 4283 | ||
4286 | /* reset offloads to defaults */ | 4284 | /* reset offloads to defaults */ |
4287 | igb_set_vmolr(hw, vf); | 4285 | igb_set_vmolr(&adapter->hw, vf); |
4288 | 4286 | ||
4289 | /* reset vlans for device */ | 4287 | /* reset vlans for device */ |
4290 | igb_clear_vf_vfta(adapter, vf); | 4288 | igb_clear_vf_vfta(adapter, vf); |
@@ -4296,7 +4294,18 @@ static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf) | |||
4296 | igb_set_rx_mode(adapter->netdev); | 4294 | igb_set_rx_mode(adapter->netdev); |
4297 | } | 4295 | } |
4298 | 4296 | ||
4299 | static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) | 4297 | static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf) |
4298 | { | ||
4299 | unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; | ||
4300 | |||
4301 | /* generate a new mac address as we were hotplug removed/added */ | ||
4302 | random_ether_addr(vf_mac); | ||
4303 | |||
4304 | /* process remaining reset events */ | ||
4305 | igb_vf_reset(adapter, vf); | ||
4306 | } | ||
4307 | |||
4308 | static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) | ||
4300 | { | 4309 | { |
4301 | struct e1000_hw *hw = &adapter->hw; | 4310 | struct e1000_hw *hw = &adapter->hw; |
4302 | unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; | 4311 | unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; |
@@ -4305,7 +4314,7 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) | |||
4305 | u8 *addr = (u8 *)(&msgbuf[1]); | 4314 | u8 *addr = (u8 *)(&msgbuf[1]); |
4306 | 4315 | ||
4307 | /* process all the same items cleared in a function level reset */ | 4316 | /* process all the same items cleared in a function level reset */ |
4308 | igb_vf_reset_event(adapter, vf); | 4317 | igb_vf_reset(adapter, vf); |
4309 | 4318 | ||
4310 | /* set vf mac address */ | 4319 | /* set vf mac address */ |
4311 | igb_rar_set_qsel(adapter, vf_mac, rar_entry, vf); | 4320 | igb_rar_set_qsel(adapter, vf_mac, rar_entry, vf); |
@@ -4316,8 +4325,7 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) | |||
4316 | reg = rd32(E1000_VFRE); | 4325 | reg = rd32(E1000_VFRE); |
4317 | wr32(E1000_VFRE, reg | (1 << vf)); | 4326 | wr32(E1000_VFRE, reg | (1 << vf)); |
4318 | 4327 | ||
4319 | /* enable mailbox functionality for vf */ | 4328 | adapter->vf_data[vf].flags = IGB_VF_FLAG_CTS; |
4320 | adapter->vf_data[vf].clear_to_send = true; | ||
4321 | 4329 | ||
4322 | /* reply to reset with ack and vf mac address */ | 4330 | /* reply to reset with ack and vf mac address */ |
4323 | msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK; | 4331 | msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK; |
@@ -4327,66 +4335,45 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) | |||
4327 | 4335 | ||
4328 | static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf) | 4336 | static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf) |
4329 | { | 4337 | { |
4330 | unsigned char *addr = (char *)&msg[1]; | 4338 | unsigned char *addr = (char *)&msg[1]; |
4331 | int err = -1; | 4339 | int err = -1; |
4332 | 4340 | ||
4333 | if (is_valid_ether_addr(addr)) | 4341 | if (is_valid_ether_addr(addr)) |
4334 | err = igb_set_vf_mac(adapter, vf, addr); | 4342 | err = igb_set_vf_mac(adapter, vf, addr); |
4335 | |||
4336 | return err; | ||
4337 | 4343 | ||
4344 | return err; | ||
4338 | } | 4345 | } |
4339 | 4346 | ||
4340 | static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf) | 4347 | static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf) |
4341 | { | 4348 | { |
4342 | struct e1000_hw *hw = &adapter->hw; | 4349 | struct e1000_hw *hw = &adapter->hw; |
4350 | struct vf_data_storage *vf_data = &adapter->vf_data[vf]; | ||
4343 | u32 msg = E1000_VT_MSGTYPE_NACK; | 4351 | u32 msg = E1000_VT_MSGTYPE_NACK; |
4344 | 4352 | ||
4345 | /* if device isn't clear to send it shouldn't be reading either */ | 4353 | /* if device isn't clear to send it shouldn't be reading either */ |
4346 | if (!adapter->vf_data[vf].clear_to_send) | 4354 | if (!(vf_data->flags & IGB_VF_FLAG_CTS) && |
4355 | time_after(jiffies, vf_data->last_nack + (2 * HZ))) { | ||
4347 | igb_write_mbx(hw, &msg, 1, vf); | 4356 | igb_write_mbx(hw, &msg, 1, vf); |
4348 | } | 4357 | vf_data->last_nack = jiffies; |
4349 | |||
4350 | |||
4351 | static void igb_msg_task(struct igb_adapter *adapter) | ||
4352 | { | ||
4353 | struct e1000_hw *hw = &adapter->hw; | ||
4354 | u32 vf; | ||
4355 | |||
4356 | for (vf = 0; vf < adapter->vfs_allocated_count; vf++) { | ||
4357 | /* process any reset requests */ | ||
4358 | if (!igb_check_for_rst(hw, vf)) { | ||
4359 | adapter->vf_data[vf].clear_to_send = false; | ||
4360 | igb_vf_reset_event(adapter, vf); | ||
4361 | } | ||
4362 | |||
4363 | /* process any messages pending */ | ||
4364 | if (!igb_check_for_msg(hw, vf)) | ||
4365 | igb_rcv_msg_from_vf(adapter, vf); | ||
4366 | |||
4367 | /* process any acks */ | ||
4368 | if (!igb_check_for_ack(hw, vf)) | ||
4369 | igb_rcv_ack_from_vf(adapter, vf); | ||
4370 | |||
4371 | } | 4358 | } |
4372 | } | 4359 | } |
4373 | 4360 | ||
4374 | static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) | 4361 | static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) |
4375 | { | 4362 | { |
4376 | u32 mbx_size = E1000_VFMAILBOX_SIZE; | 4363 | struct pci_dev *pdev = adapter->pdev; |
4377 | u32 msgbuf[mbx_size]; | 4364 | u32 msgbuf[E1000_VFMAILBOX_SIZE]; |
4378 | struct e1000_hw *hw = &adapter->hw; | 4365 | struct e1000_hw *hw = &adapter->hw; |
4366 | struct vf_data_storage *vf_data = &adapter->vf_data[vf]; | ||
4379 | s32 retval; | 4367 | s32 retval; |
4380 | 4368 | ||
4381 | retval = igb_read_mbx(hw, msgbuf, mbx_size, vf); | 4369 | retval = igb_read_mbx(hw, msgbuf, E1000_VFMAILBOX_SIZE, vf); |
4382 | 4370 | ||
4383 | if (retval) | 4371 | if (retval) |
4384 | dev_err(&adapter->pdev->dev, | 4372 | dev_err(&pdev->dev, "Error receiving message from VF\n"); |
4385 | "Error receiving message from VF\n"); | ||
4386 | 4373 | ||
4387 | /* this is a message we already processed, do nothing */ | 4374 | /* this is a message we already processed, do nothing */ |
4388 | if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK)) | 4375 | if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK)) |
4389 | return retval; | 4376 | return; |
4390 | 4377 | ||
4391 | /* | 4378 | /* |
4392 | * until the vf completes a reset it should not be | 4379 | * until the vf completes a reset it should not be |
@@ -4395,14 +4382,16 @@ static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) | |||
4395 | 4382 | ||
4396 | if (msgbuf[0] == E1000_VF_RESET) { | 4383 | if (msgbuf[0] == E1000_VF_RESET) { |
4397 | igb_vf_reset_msg(adapter, vf); | 4384 | igb_vf_reset_msg(adapter, vf); |
4398 | 4385 | return; | |
4399 | return retval; | ||
4400 | } | 4386 | } |
4401 | 4387 | ||
4402 | if (!adapter->vf_data[vf].clear_to_send) { | 4388 | if (!(vf_data->flags & IGB_VF_FLAG_CTS)) { |
4403 | msgbuf[0] |= E1000_VT_MSGTYPE_NACK; | 4389 | msgbuf[0] = E1000_VT_MSGTYPE_NACK; |
4404 | igb_write_mbx(hw, msgbuf, 1, vf); | 4390 | if (time_after(jiffies, vf_data->last_nack + (2 * HZ))) { |
4405 | return retval; | 4391 | igb_write_mbx(hw, msgbuf, 1, vf); |
4392 | vf_data->last_nack = jiffies; | ||
4393 | } | ||
4394 | return; | ||
4406 | } | 4395 | } |
4407 | 4396 | ||
4408 | switch ((msgbuf[0] & 0xFFFF)) { | 4397 | switch ((msgbuf[0] & 0xFFFF)) { |
@@ -4433,8 +4422,26 @@ static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf) | |||
4433 | msgbuf[0] |= E1000_VT_MSGTYPE_CTS; | 4422 | msgbuf[0] |= E1000_VT_MSGTYPE_CTS; |
4434 | 4423 | ||
4435 | igb_write_mbx(hw, msgbuf, 1, vf); | 4424 | igb_write_mbx(hw, msgbuf, 1, vf); |
4425 | } | ||
4436 | 4426 | ||
4437 | return retval; | 4427 | static void igb_msg_task(struct igb_adapter *adapter) |
4428 | { | ||
4429 | struct e1000_hw *hw = &adapter->hw; | ||
4430 | u32 vf; | ||
4431 | |||
4432 | for (vf = 0; vf < adapter->vfs_allocated_count; vf++) { | ||
4433 | /* process any reset requests */ | ||
4434 | if (!igb_check_for_rst(hw, vf)) | ||
4435 | igb_vf_reset_event(adapter, vf); | ||
4436 | |||
4437 | /* process any messages pending */ | ||
4438 | if (!igb_check_for_msg(hw, vf)) | ||
4439 | igb_rcv_msg_from_vf(adapter, vf); | ||
4440 | |||
4441 | /* process any acks */ | ||
4442 | if (!igb_check_for_ack(hw, vf)) | ||
4443 | igb_rcv_ack_from_vf(adapter, vf); | ||
4444 | } | ||
4438 | } | 4445 | } |
4439 | 4446 | ||
4440 | /** | 4447 | /** |