drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
Extension
.c
Size
16157 bytes
Lines
598
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (fsp->h_u.usr_ip4_spec.proto) {
		case IPPROTO_TCP:
			*flow_type = TXGBE_ATR_FLOW_TYPE_TCPV4;
			break;
		case IPPROTO_UDP:
			*flow_type = TXGBE_ATR_FLOW_TYPE_UDPV4;
			break;
		case IPPROTO_SCTP:
			*flow_type = TXGBE_ATR_FLOW_TYPE_SCTPV4;
			break;
		case 0:
			if (!fsp->m_u.usr_ip4_spec.proto) {
				*flow_type = TXGBE_ATR_FLOW_TYPE_IPV4;
				break;
			}
			fallthrough;
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static bool txgbe_match_ethtool_fdir_entry(struct txgbe *txgbe,
					   struct txgbe_fdir_filter *input)
{
	struct txgbe_fdir_filter *rule = NULL;
	struct hlist_node *node2;

	hlist_for_each_entry_safe(rule, node2, &txgbe->fdir_filter_list,
				  fdir_node) {
		if (rule->filter.formatted.bkt_hash ==
		    input->filter.formatted.bkt_hash &&
		    rule->action == input->action) {
			wx_dbg(txgbe->wx, "FDIR entry already exist\n");
			return true;
		}
	}
	return false;
}

static int txgbe_update_ethtool_fdir_entry(struct txgbe *txgbe,
					   struct txgbe_fdir_filter *input,
					   u16 sw_idx)
{
	struct hlist_node *node = NULL, *parent = NULL;
	struct txgbe_fdir_filter *rule;
	struct wx *wx = txgbe->wx;
	bool deleted = false;
	int err;

	hlist_for_each_entry_safe(rule, node, &txgbe->fdir_filter_list,
				  fdir_node) {
		/* hash found, or no matching entry */
		if (rule->sw_idx >= sw_idx)
			break;
		parent = node;
	}

	/* if there is an old rule occupying our place remove it */
	if (rule && rule->sw_idx == sw_idx) {
		/* hardware filters are only configured when interface is up,
		 * and we should not issue filter commands while the interface
		 * is down
		 */
		if (netif_running(wx->netdev) &&
		    (!input || rule->filter.formatted.bkt_hash !=
		     input->filter.formatted.bkt_hash)) {
			err = txgbe_fdir_erase_perfect_filter(wx,
							      &rule->filter,
							      sw_idx);
			if (err)
				return -EINVAL;
		}

		hlist_del(&rule->fdir_node);
		kfree(rule);
		txgbe->fdir_filter_count--;
		deleted = true;
	}

	/* If we weren't given an input, then this was a request to delete a
	 * filter. We should return -EINVAL if the filter wasn't found, but
	 * return 0 if the rule was successfully deleted.
	 */
	if (!input)

Annotation

Implementation Notes