aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2014-09-20 19:47:58 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2014-09-23 06:59:15 -0400
commit401b5383c6c9c5b85e1a60bf9de4c7f2dd09d114 (patch)
tree95ef13d3ff4734d56dff6be17dccbf6b6f5e212b /drivers/net
parentb6fec18fd16bbf719c1c0aa83e41590573b4c58c (diff)
fm10k: Add support for configuring PF interface
This patch adds support for the operations which will configure filters on the interface. In addition with these patches we begin to introduce the PF messages that will be sent to or received from the Switch Management entity. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.c587
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.h98
2 files changed, 683 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
index b798cd5a7935..8da382ccf22b 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
@@ -181,6 +181,66 @@ static bool fm10k_is_slot_appropriate_pf(struct fm10k_hw *hw)
181} 181}
182 182
183/** 183/**
184 * fm10k_update_vlan_pf - Update status of VLAN ID in VLAN filter table
185 * @hw: pointer to hardware structure
186 * @vid: VLAN ID to add to table
187 * @vsi: Index indicating VF ID or PF ID in table
188 * @set: Indicates if this is a set or clear operation
189 *
190 * This function adds or removes the corresponding VLAN ID from the VLAN
191 * filter table for the corresponding function. In addition to the
192 * standard set/clear that supports one bit a multi-bit write is
193 * supported to set 64 bits at a time.
194 **/
195static s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set)
196{
197 u32 vlan_table, reg, mask, bit, len;
198
199 /* verify the VSI index is valid */
200 if (vsi > FM10K_VLAN_TABLE_VSI_MAX)
201 return FM10K_ERR_PARAM;
202
203 /* VLAN multi-bit write:
204 * The multi-bit write has several parts to it.
205 * 3 2 1 0
206 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
207 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208 * | RSVD0 | Length |C|RSVD0| VLAN ID |
209 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210 *
211 * VLAN ID: Vlan Starting value
212 * RSVD0: Reserved section, must be 0
213 * C: Flag field, 0 is set, 1 is clear (Used in VF VLAN message)
214 * Length: Number of times to repeat the bit being set
215 */
216 len = vid >> 16;
217 vid = (vid << 17) >> 17;
218
219 /* verify the reserved 0 fields are 0 */
220 if (len >= FM10K_VLAN_TABLE_VID_MAX ||
221 vid >= FM10K_VLAN_TABLE_VID_MAX)
222 return FM10K_ERR_PARAM;
223
224 /* Loop through the table updating all required VLANs */
225 for (reg = FM10K_VLAN_TABLE(vsi, vid / 32), bit = vid % 32;
226 len < FM10K_VLAN_TABLE_VID_MAX;
227 len -= 32 - bit, reg++, bit = 0) {
228 /* record the initial state of the register */
229 vlan_table = fm10k_read_reg(hw, reg);
230
231 /* truncate mask if we are at the start or end of the run */
232 mask = (~(u32)0 >> ((len < 31) ? 31 - len : 0)) << bit;
233
234 /* make necessary modifications to the register */
235 mask &= set ? ~vlan_table : vlan_table;
236 if (mask)
237 fm10k_write_reg(hw, reg, vlan_table ^ mask);
238 }
239
240 return 0;
241}
242
243/**
184 * fm10k_read_mac_addr_pf - Read device MAC address 244 * fm10k_read_mac_addr_pf - Read device MAC address
185 * @hw: pointer to the HW structure 245 * @hw: pointer to the HW structure
186 * 246 *
@@ -221,6 +281,297 @@ static s32 fm10k_read_mac_addr_pf(struct fm10k_hw *hw)
221} 281}
222 282
223/** 283/**
284 * fm10k_glort_valid_pf - Validate that the provided glort is valid
285 * @hw: pointer to the HW structure
286 * @glort: base glort to be validated
287 *
288 * This function will return an error if the provided glort is invalid
289 **/
290bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort)
291{
292 glort &= hw->mac.dglort_map >> FM10K_DGLORTMAP_MASK_SHIFT;
293
294 return glort == (hw->mac.dglort_map & FM10K_DGLORTMAP_NONE);
295}
296
297/**
298 * fm10k_update_uc_addr_pf - Update device unicast addresss
299 * @hw: pointer to the HW structure
300 * @glort: base resource tag for this request
301 * @mac: MAC address to add/remove from table
302 * @vid: VLAN ID to add/remove from table
303 * @add: Indicates if this is an add or remove operation
304 * @flags: flags field to indicate add and secure
305 *
306 * This function generates a message to the Switch API requesting
307 * that the given logical port add/remove the given L2 MAC/VLAN address.
308 **/
309static s32 fm10k_update_xc_addr_pf(struct fm10k_hw *hw, u16 glort,
310 const u8 *mac, u16 vid, bool add, u8 flags)
311{
312 struct fm10k_mbx_info *mbx = &hw->mbx;
313 struct fm10k_mac_update mac_update;
314 u32 msg[5];
315
316 /* if glort is not valid return error */
317 if (!fm10k_glort_valid_pf(hw, glort))
318 return FM10K_ERR_PARAM;
319
320 /* drop upper 4 bits of VLAN ID */
321 vid = (vid << 4) >> 4;
322
323 /* record fields */
324 mac_update.mac_lower = cpu_to_le32(((u32)mac[2] << 24) |
325 ((u32)mac[3] << 16) |
326 ((u32)mac[4] << 8) |
327 ((u32)mac[5]));
328 mac_update.mac_upper = cpu_to_le16(((u32)mac[0] << 8) |
329 ((u32)mac[1]));
330 mac_update.vlan = cpu_to_le16(vid);
331 mac_update.glort = cpu_to_le16(glort);
332 mac_update.action = add ? 0 : 1;
333 mac_update.flags = flags;
334
335 /* populate mac_update fields */
336 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE);
337 fm10k_tlv_attr_put_le_struct(msg, FM10K_PF_ATTR_ID_MAC_UPDATE,
338 &mac_update, sizeof(mac_update));
339
340 /* load onto outgoing mailbox */
341 return mbx->ops.enqueue_tx(hw, mbx, msg);
342}
343
344/**
345 * fm10k_update_uc_addr_pf - Update device unicast addresss
346 * @hw: pointer to the HW structure
347 * @glort: base resource tag for this request
348 * @mac: MAC address to add/remove from table
349 * @vid: VLAN ID to add/remove from table
350 * @add: Indicates if this is an add or remove operation
351 * @flags: flags field to indicate add and secure
352 *
353 * This function is used to add or remove unicast addresses for
354 * the PF.
355 **/
356static s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,
357 const u8 *mac, u16 vid, bool add, u8 flags)
358{
359 /* verify MAC address is valid */
360 if (!is_valid_ether_addr(mac))
361 return FM10K_ERR_PARAM;
362
363 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);
364}
365
366/**
367 * fm10k_update_mc_addr_pf - Update device multicast addresses
368 * @hw: pointer to the HW structure
369 * @glort: base resource tag for this request
370 * @mac: MAC address to add/remove from table
371 * @vid: VLAN ID to add/remove from table
372 * @add: Indicates if this is an add or remove operation
373 *
374 * This function is used to add or remove multicast MAC addresses for
375 * the PF.
376 **/
377static s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,
378 const u8 *mac, u16 vid, bool add)
379{
380 /* verify multicast address is valid */
381 if (!is_multicast_ether_addr(mac))
382 return FM10K_ERR_PARAM;
383
384 return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);
385}
386
387/**
388 * fm10k_update_xcast_mode_pf - Request update of multicast mode
389 * @hw: pointer to hardware structure
390 * @glort: base resource tag for this request
391 * @mode: integer value indicating mode being requested
392 *
393 * This function will attempt to request a higher mode for the port
394 * so that it can enable either multicast, multicast promiscuous, or
395 * promiscuous mode of operation.
396 **/
397static s32 fm10k_update_xcast_mode_pf(struct fm10k_hw *hw, u16 glort, u8 mode)
398{
399 struct fm10k_mbx_info *mbx = &hw->mbx;
400 u32 msg[3], xcast_mode;
401
402 if (mode > FM10K_XCAST_MODE_NONE)
403 return FM10K_ERR_PARAM;
404 /* if glort is not valid return error */
405 if (!fm10k_glort_valid_pf(hw, glort))
406 return FM10K_ERR_PARAM;
407
408 /* write xcast mode as a single u32 value,
409 * lower 16 bits: glort
410 * upper 16 bits: mode
411 */
412 xcast_mode = ((u32)mode << 16) | glort;
413
414 /* generate message requesting to change xcast mode */
415 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_XCAST_MODES);
416 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_XCAST_MODE, xcast_mode);
417
418 /* load onto outgoing mailbox */
419 return mbx->ops.enqueue_tx(hw, mbx, msg);
420}
421
422/**
423 * fm10k_update_int_moderator_pf - Update interrupt moderator linked list
424 * @hw: pointer to hardware structure
425 *
426 * This function walks through the MSI-X vector table to determine the
427 * number of active interrupts and based on that information updates the
428 * interrupt moderator linked list.
429 **/
430static void fm10k_update_int_moderator_pf(struct fm10k_hw *hw)
431{
432 u32 i;
433
434 /* Disable interrupt moderator */
435 fm10k_write_reg(hw, FM10K_INT_CTRL, 0);
436
437 /* loop through PF from last to first looking enabled vectors */
438 for (i = FM10K_ITR_REG_COUNT_PF - 1; i; i--) {
439 if (!fm10k_read_reg(hw, FM10K_MSIX_VECTOR_MASK(i)))
440 break;
441 }
442
443 /* always reset VFITR2[0] to point to last enabled PF vector*/
444 fm10k_write_reg(hw, FM10K_ITR2(FM10K_ITR_REG_COUNT_PF), i);
445
446 /* reset ITR2[0] to point to last enabled PF vector */
447 fm10k_write_reg(hw, FM10K_ITR2(0), i);
448
449 /* Enable interrupt moderator */
450 fm10k_write_reg(hw, FM10K_INT_CTRL, FM10K_INT_CTRL_ENABLEMODERATOR);
451}
452
453/**
454 * fm10k_update_lport_state_pf - Notify the switch of a change in port state
455 * @hw: pointer to the HW structure
456 * @glort: base resource tag for this request
457 * @count: number of logical ports being updated
458 * @enable: boolean value indicating enable or disable
459 *
460 * This function is used to add/remove a logical port from the switch.
461 **/
462static s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort,
463 u16 count, bool enable)
464{
465 struct fm10k_mbx_info *mbx = &hw->mbx;
466 u32 msg[3], lport_msg;
467
468 /* do nothing if we are being asked to create or destroy 0 ports */
469 if (!count)
470 return 0;
471
472 /* if glort is not valid return error */
473 if (!fm10k_glort_valid_pf(hw, glort))
474 return FM10K_ERR_PARAM;
475
476 /* construct the lport message from the 2 pieces of data we have */
477 lport_msg = ((u32)count << 16) | glort;
478
479 /* generate lport create/delete message */
480 fm10k_tlv_msg_init(msg, enable ? FM10K_PF_MSG_ID_LPORT_CREATE :
481 FM10K_PF_MSG_ID_LPORT_DELETE);
482 fm10k_tlv_attr_put_u32(msg, FM10K_PF_ATTR_ID_PORT, lport_msg);
483
484 /* load onto outgoing mailbox */
485 return mbx->ops.enqueue_tx(hw, mbx, msg);
486}
487
488/**
489 * fm10k_configure_dglort_map_pf - Configures GLORT entry and queues
490 * @hw: pointer to hardware structure
491 * @dglort: pointer to dglort configuration structure
492 *
493 * Reads the configuration structure contained in dglort_cfg and uses
494 * that information to then populate a DGLORTMAP/DEC entry and the queues
495 * to which it has been assigned.
496 **/
497static s32 fm10k_configure_dglort_map_pf(struct fm10k_hw *hw,
498 struct fm10k_dglort_cfg *dglort)
499{
500 u16 glort, queue_count, vsi_count, pc_count;
501 u16 vsi, queue, pc, q_idx;
502 u32 txqctl, dglortdec, dglortmap;
503
504 /* verify the dglort pointer */
505 if (!dglort)
506 return FM10K_ERR_PARAM;
507
508 /* verify the dglort values */
509 if ((dglort->idx > 7) || (dglort->rss_l > 7) || (dglort->pc_l > 3) ||
510 (dglort->vsi_l > 6) || (dglort->vsi_b > 64) ||
511 (dglort->queue_l > 8) || (dglort->queue_b >= 256))
512 return FM10K_ERR_PARAM;
513
514 /* determine count of VSIs and queues */
515 queue_count = 1 << (dglort->rss_l + dglort->pc_l);
516 vsi_count = 1 << (dglort->vsi_l + dglort->queue_l);
517 glort = dglort->glort;
518 q_idx = dglort->queue_b;
519
520 /* configure SGLORT for queues */
521 for (vsi = 0; vsi < vsi_count; vsi++, glort++) {
522 for (queue = 0; queue < queue_count; queue++, q_idx++) {
523 if (q_idx >= FM10K_MAX_QUEUES)
524 break;
525
526 fm10k_write_reg(hw, FM10K_TX_SGLORT(q_idx), glort);
527 fm10k_write_reg(hw, FM10K_RX_SGLORT(q_idx), glort);
528 }
529 }
530
531 /* determine count of PCs and queues */
532 queue_count = 1 << (dglort->queue_l + dglort->rss_l + dglort->vsi_l);
533 pc_count = 1 << dglort->pc_l;
534
535 /* configure PC for Tx queues */
536 for (pc = 0; pc < pc_count; pc++) {
537 q_idx = pc + dglort->queue_b;
538 for (queue = 0; queue < queue_count; queue++) {
539 if (q_idx >= FM10K_MAX_QUEUES)
540 break;
541
542 txqctl = fm10k_read_reg(hw, FM10K_TXQCTL(q_idx));
543 txqctl &= ~FM10K_TXQCTL_PC_MASK;
544 txqctl |= pc << FM10K_TXQCTL_PC_SHIFT;
545 fm10k_write_reg(hw, FM10K_TXQCTL(q_idx), txqctl);
546
547 q_idx += pc_count;
548 }
549 }
550
551 /* configure DGLORTDEC */
552 dglortdec = ((u32)(dglort->rss_l) << FM10K_DGLORTDEC_RSSLENGTH_SHIFT) |
553 ((u32)(dglort->queue_b) << FM10K_DGLORTDEC_QBASE_SHIFT) |
554 ((u32)(dglort->pc_l) << FM10K_DGLORTDEC_PCLENGTH_SHIFT) |
555 ((u32)(dglort->vsi_b) << FM10K_DGLORTDEC_VSIBASE_SHIFT) |
556 ((u32)(dglort->vsi_l) << FM10K_DGLORTDEC_VSILENGTH_SHIFT) |
557 ((u32)(dglort->queue_l));
558 if (dglort->inner_rss)
559 dglortdec |= FM10K_DGLORTDEC_INNERRSS_ENABLE;
560
561 /* configure DGLORTMAP */
562 dglortmap = (dglort->idx == fm10k_dglort_default) ?
563 FM10K_DGLORTMAP_ANY : FM10K_DGLORTMAP_ZERO;
564 dglortmap <<= dglort->vsi_l + dglort->queue_l + dglort->shared_l;
565 dglortmap |= dglort->glort;
566
567 /* write values to hardware */
568 fm10k_write_reg(hw, FM10K_DGLORTDEC(dglort->idx), dglortdec);
569 fm10k_write_reg(hw, FM10K_DGLORTMAP(dglort->idx), dglortmap);
570
571 return 0;
572}
573
574/**
224 * fm10k_update_stats_hw_pf - Updates hardware related statistics of PF 575 * fm10k_update_stats_hw_pf - Updates hardware related statistics of PF
225 * @hw: pointer to hardware structure 576 * @hw: pointer to hardware structure
226 * @stats: pointer to the stats structure to update 577 * @stats: pointer to the stats structure to update
@@ -319,6 +670,22 @@ static void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
319} 670}
320 671
321/** 672/**
673 * fm10k_set_dma_mask_pf - Configures PhyAddrSpace to limit DMA to system
674 * @hw: pointer to hardware structure
675 * @dma_mask: 64 bit DMA mask required for platform
676 *
677 * This function sets the PHYADDR.PhyAddrSpace bits for the endpoint in order
678 * to limit the access to memory beyond what is physically in the system.
679 **/
680static void fm10k_set_dma_mask_pf(struct fm10k_hw *hw, u64 dma_mask)
681{
682 /* we need to write the upper 32 bits of DMA mask to PhyAddrSpace */
683 u32 phyaddr = (u32)(dma_mask >> 32);
684
685 fm10k_write_reg(hw, FM10K_PHYADDR, phyaddr);
686}
687
688/**
322 * fm10k_get_fault_pf - Record a fault in one of the interface units 689 * fm10k_get_fault_pf - Record a fault in one of the interface units
323 * @hw: pointer to hardware structure 690 * @hw: pointer to hardware structure
324 * @type: pointer to fault type register offset 691 * @type: pointer to fault type register offset
@@ -371,6 +738,207 @@ static s32 fm10k_get_fault_pf(struct fm10k_hw *hw, int type,
371 return 0; 738 return 0;
372} 739}
373 740
741/**
742 * fm10k_request_lport_map_pf - Request LPORT map from the switch API
743 * @hw: pointer to hardware structure
744 *
745 **/
746static s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)
747{
748 struct fm10k_mbx_info *mbx = &hw->mbx;
749 u32 msg[1];
750
751 /* issue request asking for LPORT map */
752 fm10k_tlv_msg_init(msg, FM10K_PF_MSG_ID_LPORT_MAP);
753
754 /* load onto outgoing mailbox */
755 return mbx->ops.enqueue_tx(hw, mbx, msg);
756}
757
758/**
759 * fm10k_get_host_state_pf - Returns the state of the switch and mailbox
760 * @hw: pointer to hardware structure
761 * @switch_ready: pointer to boolean value that will record switch state
762 *
763 * This funciton will check the DMA_CTRL2 register and mailbox in order
764 * to determine if the switch is ready for the PF to begin requesting
765 * addresses and mapping traffic to the local interface.
766 **/
767static s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
768{
769 s32 ret_val = 0;
770 u32 dma_ctrl2;
771
772 /* verify the switch is ready for interraction */
773 dma_ctrl2 = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
774 if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))
775 goto out;
776
777 /* retrieve generic host state info */
778 ret_val = fm10k_get_host_state_generic(hw, switch_ready);
779 if (ret_val)
780 goto out;
781
782 /* interface cannot receive traffic without logical ports */
783 if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
784 ret_val = fm10k_request_lport_map_pf(hw);
785
786out:
787 return ret_val;
788}
789
790/* This structure defines the attibutes to be parsed below */
791const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {
792 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),
793 FM10K_TLV_ATTR_LAST
794};
795
796/**
797 * fm10k_msg_lport_map_pf - Message handler for lport_map message from SM
798 * @hw: Pointer to hardware structure
799 * @results: pointer array containing parsed data
800 * @mbx: Pointer to mailbox information structure
801 *
802 * This handler configures the lport mapping based on the reply from the
803 * switch API.
804 **/
805s32 fm10k_msg_lport_map_pf(struct fm10k_hw *hw, u32 **results,
806 struct fm10k_mbx_info *mbx)
807{
808 u16 glort, mask;
809 u32 dglort_map;
810 s32 err;
811
812 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_LPORT_MAP],
813 &dglort_map);
814 if (err)
815 return err;
816
817 /* extract values out of the header */
818 glort = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_GLORT);
819 mask = FM10K_MSG_HDR_FIELD_GET(dglort_map, LPORT_MAP_MASK);
820
821 /* verify mask is set and none of the masked bits in glort are set */
822 if (!mask || (glort & ~mask))
823 return FM10K_ERR_PARAM;
824
825 /* verify the mask is contiguous, and that it is 1's followed by 0's */
826 if (((~(mask - 1) & mask) + mask) & FM10K_DGLORTMAP_NONE)
827 return FM10K_ERR_PARAM;
828
829 /* record the glort, mask, and port count */
830 hw->mac.dglort_map = dglort_map;
831
832 return 0;
833}
834
835const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[] = {
836 FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_UPDATE_PVID),
837 FM10K_TLV_ATTR_LAST
838};
839
840/**
841 * fm10k_msg_update_pvid_pf - Message handler for port VLAN message from SM
842 * @hw: Pointer to hardware structure
843 * @results: pointer array containing parsed data
844 * @mbx: Pointer to mailbox information structure
845 *
846 * This handler configures the default VLAN for the PF
847 **/
848s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *hw, u32 **results,
849 struct fm10k_mbx_info *mbx)
850{
851 u16 glort, pvid;
852 u32 pvid_update;
853 s32 err;
854
855 err = fm10k_tlv_attr_get_u32(results[FM10K_PF_ATTR_ID_UPDATE_PVID],
856 &pvid_update);
857 if (err)
858 return err;
859
860 /* extract values from the pvid update */
861 glort = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_GLORT);
862 pvid = FM10K_MSG_HDR_FIELD_GET(pvid_update, UPDATE_PVID_PVID);
863
864 /* if glort is not valid return error */
865 if (!fm10k_glort_valid_pf(hw, glort))
866 return FM10K_ERR_PARAM;
867
868 /* verify VID is valid */
869 if (pvid >= FM10K_VLAN_TABLE_VID_MAX)
870 return FM10K_ERR_PARAM;
871
872 /* record the port VLAN ID value */
873 hw->mac.default_vid = pvid;
874
875 return 0;
876}
877
878/**
879 * fm10k_record_global_table_data - Move global table data to swapi table info
880 * @from: pointer to source table data structure
881 * @to: pointer to destination table info structure
882 *
883 * This function is will copy table_data to the table_info contained in
884 * the hw struct.
885 **/
886static void fm10k_record_global_table_data(struct fm10k_global_table_data *from,
887 struct fm10k_swapi_table_info *to)
888{
889 /* convert from le32 struct to CPU byte ordered values */
890 to->used = le32_to_cpu(from->used);
891 to->avail = le32_to_cpu(from->avail);
892}
893
894const struct fm10k_tlv_attr fm10k_err_msg_attr[] = {
895 FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
896 sizeof(struct fm10k_swapi_error)),
897 FM10K_TLV_ATTR_LAST
898};
899
900/**
901 * fm10k_msg_err_pf - Message handler for error reply
902 * @hw: Pointer to hardware structure
903 * @results: pointer array containing parsed data
904 * @mbx: Pointer to mailbox information structure
905 *
906 * This handler will capture the data for any error replies to previous
907 * messages that the PF has sent.
908 **/
909s32 fm10k_msg_err_pf(struct fm10k_hw *hw, u32 **results,
910 struct fm10k_mbx_info *mbx)
911{
912 struct fm10k_swapi_error err_msg;
913 s32 err;
914
915 /* extract structure from message */
916 err = fm10k_tlv_attr_get_le_struct(results[FM10K_PF_ATTR_ID_ERR],
917 &err_msg, sizeof(err_msg));
918 if (err)
919 return err;
920
921 /* record table status */
922 fm10k_record_global_table_data(&err_msg.mac, &hw->swapi.mac);
923 fm10k_record_global_table_data(&err_msg.nexthop, &hw->swapi.nexthop);
924 fm10k_record_global_table_data(&err_msg.ffu, &hw->swapi.ffu);
925
926 /* record SW API status value */
927 hw->swapi.status = le32_to_cpu(err_msg.status);
928
929 return 0;
930}
931
932static const struct fm10k_msg_data fm10k_msg_data_pf[] = {
933 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
934 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
935 FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
936 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
937 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
938 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
939 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
940};
941
374static struct fm10k_mac_ops mac_ops_pf = { 942static struct fm10k_mac_ops mac_ops_pf = {
375 .get_bus_info = &fm10k_get_bus_info_generic, 943 .get_bus_info = &fm10k_get_bus_info_generic,
376 .reset_hw = &fm10k_reset_hw_pf, 944 .reset_hw = &fm10k_reset_hw_pf,
@@ -378,15 +946,30 @@ static struct fm10k_mac_ops mac_ops_pf = {
378 .start_hw = &fm10k_start_hw_generic, 946 .start_hw = &fm10k_start_hw_generic,
379 .stop_hw = &fm10k_stop_hw_generic, 947 .stop_hw = &fm10k_stop_hw_generic,
380 .is_slot_appropriate = &fm10k_is_slot_appropriate_pf, 948 .is_slot_appropriate = &fm10k_is_slot_appropriate_pf,
949 .update_vlan = &fm10k_update_vlan_pf,
381 .read_mac_addr = &fm10k_read_mac_addr_pf, 950 .read_mac_addr = &fm10k_read_mac_addr_pf,
951 .update_uc_addr = &fm10k_update_uc_addr_pf,
952 .update_mc_addr = &fm10k_update_mc_addr_pf,
953 .update_xcast_mode = &fm10k_update_xcast_mode_pf,
954 .update_int_moderator = &fm10k_update_int_moderator_pf,
955 .update_lport_state = &fm10k_update_lport_state_pf,
382 .update_hw_stats = &fm10k_update_hw_stats_pf, 956 .update_hw_stats = &fm10k_update_hw_stats_pf,
383 .rebind_hw_stats = &fm10k_rebind_hw_stats_pf, 957 .rebind_hw_stats = &fm10k_rebind_hw_stats_pf,
958 .configure_dglort_map = &fm10k_configure_dglort_map_pf,
959 .set_dma_mask = &fm10k_set_dma_mask_pf,
384 .get_fault = &fm10k_get_fault_pf, 960 .get_fault = &fm10k_get_fault_pf,
385 .get_host_state = &fm10k_get_host_state_generic, 961 .get_host_state = &fm10k_get_host_state_pf,
386}; 962};
387 963
964static s32 fm10k_get_invariants_pf(struct fm10k_hw *hw)
965{
966 fm10k_get_invariants_generic(hw);
967
968 return fm10k_sm_mbx_init(hw, &hw->mbx, fm10k_msg_data_pf);
969}
970
388struct fm10k_info fm10k_pf_info = { 971struct fm10k_info fm10k_pf_info = {
389 .mac = fm10k_mac_pf, 972 .mac = fm10k_mac_pf,
390 .get_invariants = &fm10k_get_invariants_generic, 973 .get_invariants = &fm10k_get_invariants_pf,
391 .mac_ops = &mac_ops_pf, 974 .mac_ops = &mac_ops_pf,
392}; 975};
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.h b/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
index 054392ffbd10..108a7a741bb5 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.h
@@ -24,5 +24,103 @@
24#include "fm10k_type.h" 24#include "fm10k_type.h"
25#include "fm10k_common.h" 25#include "fm10k_common.h"
26 26
27bool fm10k_glort_valid_pf(struct fm10k_hw *hw, u16 glort);
28
29enum fm10k_pf_tlv_msg_id_v1 {
30 FM10K_PF_MSG_ID_TEST = 0x000, /* msg ID reserved */
31 FM10K_PF_MSG_ID_XCAST_MODES = 0x001,
32 FM10K_PF_MSG_ID_UPDATE_MAC_FWD_RULE = 0x002,
33 FM10K_PF_MSG_ID_LPORT_MAP = 0x100,
34 FM10K_PF_MSG_ID_LPORT_CREATE = 0x200,
35 FM10K_PF_MSG_ID_LPORT_DELETE = 0x201,
36 FM10K_PF_MSG_ID_CONFIG = 0x300,
37 FM10K_PF_MSG_ID_UPDATE_PVID = 0x400,
38 FM10K_PF_MSG_ID_CREATE_FLOW_TABLE = 0x501,
39 FM10K_PF_MSG_ID_DELETE_FLOW_TABLE = 0x502,
40 FM10K_PF_MSG_ID_UPDATE_FLOW = 0x503,
41 FM10K_PF_MSG_ID_DELETE_FLOW = 0x504,
42 FM10K_PF_MSG_ID_SET_FLOW_STATE = 0x505,
43 FM10K_PF_MSG_ID_GET_1588_INFO = 0x506,
44 FM10K_PF_MSG_ID_1588_TIMESTAMP = 0x701,
45};
46
47enum fm10k_pf_tlv_attr_id_v1 {
48 FM10K_PF_ATTR_ID_ERR = 0x00,
49 FM10K_PF_ATTR_ID_LPORT_MAP = 0x01,
50 FM10K_PF_ATTR_ID_XCAST_MODE = 0x02,
51 FM10K_PF_ATTR_ID_MAC_UPDATE = 0x03,
52 FM10K_PF_ATTR_ID_VLAN_UPDATE = 0x04,
53 FM10K_PF_ATTR_ID_CONFIG = 0x05,
54 FM10K_PF_ATTR_ID_CREATE_FLOW_TABLE = 0x06,
55 FM10K_PF_ATTR_ID_DELETE_FLOW_TABLE = 0x07,
56 FM10K_PF_ATTR_ID_UPDATE_FLOW = 0x08,
57 FM10K_PF_ATTR_ID_FLOW_STATE = 0x09,
58 FM10K_PF_ATTR_ID_FLOW_HANDLE = 0x0A,
59 FM10K_PF_ATTR_ID_DELETE_FLOW = 0x0B,
60 FM10K_PF_ATTR_ID_PORT = 0x0C,
61 FM10K_PF_ATTR_ID_UPDATE_PVID = 0x0D,
62 FM10K_PF_ATTR_ID_1588_TIMESTAMP = 0x10,
63};
64
65#define FM10K_MSG_LPORT_MAP_GLORT_SHIFT 0
66#define FM10K_MSG_LPORT_MAP_GLORT_SIZE 16
67#define FM10K_MSG_LPORT_MAP_MASK_SHIFT 16
68#define FM10K_MSG_LPORT_MAP_MASK_SIZE 16
69
70#define FM10K_MSG_UPDATE_PVID_GLORT_SHIFT 0
71#define FM10K_MSG_UPDATE_PVID_GLORT_SIZE 16
72#define FM10K_MSG_UPDATE_PVID_PVID_SHIFT 16
73#define FM10K_MSG_UPDATE_PVID_PVID_SIZE 16
74
75struct fm10k_mac_update {
76 __le32 mac_lower;
77 __le16 mac_upper;
78 __le16 vlan;
79 __le16 glort;
80 u8 flags;
81 u8 action;
82};
83
84struct fm10k_global_table_data {
85 __le32 used;
86 __le32 avail;
87};
88
89struct fm10k_swapi_error {
90 __le32 status;
91 struct fm10k_global_table_data mac;
92 struct fm10k_global_table_data nexthop;
93 struct fm10k_global_table_data ffu;
94};
95
96struct fm10k_swapi_1588_timestamp {
97 __le64 egress;
98 __le64 ingress;
99 __le16 dglort;
100 __le16 sglort;
101};
102
103s32 fm10k_msg_lport_map_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);
104extern const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[];
105#define FM10K_PF_MSG_LPORT_MAP_HANDLER(func) \
106 FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_LPORT_MAP, \
107 fm10k_lport_map_msg_attr, func)
108s32 fm10k_msg_update_pvid_pf(struct fm10k_hw *, u32 **,
109 struct fm10k_mbx_info *);
110extern const struct fm10k_tlv_attr fm10k_update_pvid_msg_attr[];
111#define FM10K_PF_MSG_UPDATE_PVID_HANDLER(func) \
112 FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_UPDATE_PVID, \
113 fm10k_update_pvid_msg_attr, func)
114
115s32 fm10k_msg_err_pf(struct fm10k_hw *, u32 **, struct fm10k_mbx_info *);
116extern const struct fm10k_tlv_attr fm10k_err_msg_attr[];
117#define FM10K_PF_MSG_ERR_HANDLER(msg, func) \
118 FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_##msg, fm10k_err_msg_attr, func)
119
120extern const struct fm10k_tlv_attr fm10k_1588_timestamp_msg_attr[];
121#define FM10K_PF_MSG_1588_TIMESTAMP_HANDLER(func) \
122 FM10K_MSG_HANDLER(FM10K_PF_MSG_ID_1588_TIMESTAMP, \
123 fm10k_1588_timestamp_msg_attr, func)
124
27extern struct fm10k_info fm10k_pf_info; 125extern struct fm10k_info fm10k_pf_info;
28#endif /* _FM10K_PF_H */ 126#endif /* _FM10K_PF_H */