mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	Update kernel 6.12 patches
This commit is contained in:
		
							parent
							
								
									94a20cce9c
								
							
						
					
					
						commit
						4ca673613f
					
				
					 62 changed files with 7522 additions and 780 deletions
				
			
		| 
						 | 
				
			
			@ -1,541 +0,0 @@
 | 
			
		|||
--- a/net/wireless/trace.h	2024-09-13 13:11:10.145025393 +0200
 | 
			
		||||
+++ b/net/wireless/trace.h	2024-09-13 13:14:21.774308452 +0200
 | 
			
		||||
@@ -372,7 +372,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
 		WIPHY_ASSIGN;
 | 
			
		||||
-		__assign_str(vir_intf_name, name ? name : "<noname>");
 | 
			
		||||
+		__assign_str(vir_intf_name);
 | 
			
		||||
 		__entry->type = type;
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk(WIPHY_PR_FMT ", virtual intf name: %s, type: %d",
 | 
			
		||||
--- a/net/mac80211/trace.h	2024-09-13 13:27:20.887264216 +0200
 | 
			
		||||
+++ b/net/mac80211/trace.h	2024-09-13 13:29:33.057391014 +0200
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
 			__string(vif_name, sdata->name)
 | 
			
		||||
 #define VIF_ASSIGN	__entry->vif_type = sdata->vif.type; __entry->sdata = sdata;	\
 | 
			
		||||
 			__entry->p2p = sdata->vif.p2p;					\
 | 
			
		||||
-			__assign_str(vif_name, sdata->name)
 | 
			
		||||
+			__assign_str(vif_name)
 | 
			
		||||
 #define VIF_PR_FMT	" vif:%s(%d%s)"
 | 
			
		||||
 #define VIF_PR_ARG	__get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/bus/mhi/host/trace.h	2024-09-13 13:31:32.207702337 +0200
 | 
			
		||||
+++ b/drivers/bus/mhi/host/trace.h	2024-09-13 13:32:22.330991957 +0200
 | 
			
		||||
@@ -103,7 +103,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(name, mhi_cntrl->mhi_dev->name);
 | 
			
		||||
+		__assign_str(name);
 | 
			
		||||
 		__entry->ch_num = mhi_chan->chan;
 | 
			
		||||
 		__entry->wp = mhi_tre;
 | 
			
		||||
 		__entry->tre_ptr = mhi_tre->ptr;
 | 
			
		||||
@@ -131,7 +131,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(name, mhi_cntrl->mhi_dev->name);
 | 
			
		||||
+		__assign_str(name);
 | 
			
		||||
 		__entry->local_ee = mhi_cntrl->ee;
 | 
			
		||||
 		__entry->state = mhi_cntrl->dev_state;
 | 
			
		||||
 		__entry->dev_ee = dev_ee;
 | 
			
		||||
@@ -158,7 +158,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(name, mhi_cntrl->mhi_dev->name);
 | 
			
		||||
+		__assign_str(name);
 | 
			
		||||
 		if (pm_state)
 | 
			
		||||
 			pm_state = __fls(pm_state);
 | 
			
		||||
 		__entry->pm_state = pm_state;
 | 
			
		||||
@@ -184,7 +184,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(name, mhi_cntrl->mhi_dev->name);
 | 
			
		||||
+		__assign_str(name);
 | 
			
		||||
 		__entry->rp = rp;
 | 
			
		||||
 		__entry->ptr = rp->ptr;
 | 
			
		||||
 		__entry->dword0 = rp->dword[0];
 | 
			
		||||
@@ -226,7 +226,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(name, mhi_cntrl->mhi_dev->name);
 | 
			
		||||
+		__assign_str(name);
 | 
			
		||||
 		__entry->ch_num = mhi_chan->chan;
 | 
			
		||||
 		__entry->state = state;
 | 
			
		||||
 		__entry->reason = reason;
 | 
			
		||||
@@ -265,7 +265,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(name, mhi_cntrl->mhi_dev->name);
 | 
			
		||||
+		__assign_str(name);
 | 
			
		||||
 		__entry->state = state;
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath10k/trace.h	2024-09-13 13:31:32.087704038 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath10k/trace.h	2024-09-13 13:35:37.760222205 +0200
 | 
			
		||||
@@ -55,8 +55,8 @@
 | 
			
		||||
 		__vstring(msg, vaf->fmt, vaf->va)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk(
 | 
			
		||||
@@ -92,8 +92,8 @@
 | 
			
		||||
 		__vstring(msg, vaf->fmt, vaf->va)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->level = level;
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -121,10 +121,10 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
-		__assign_str(msg, msg);
 | 
			
		||||
-		__assign_str(prefix, prefix);
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
+		__assign_str(msg);
 | 
			
		||||
+		__assign_str(prefix);
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -152,8 +152,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->id = id;
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
@@ -182,8 +182,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->id = id;
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
@@ -211,8 +211,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -239,8 +239,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->hw_type = ar->hw_rev;
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
@@ -269,8 +269,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->hw_type = ar->hw_rev;
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(pktlog), buf, buf_len);
 | 
			
		||||
@@ -301,8 +301,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->msdu_id = msdu_id;
 | 
			
		||||
 		__entry->msdu_len = msdu_len;
 | 
			
		||||
 		__entry->vdev_id = vdev_id;
 | 
			
		||||
@@ -332,8 +332,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->msdu_id = msdu_id;
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
@@ -358,8 +358,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = ath10k_frm_hdr_len(data, len);
 | 
			
		||||
 		memcpy(__get_dynamic_array(data), data, __entry->len);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -386,8 +386,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len - ath10k_frm_hdr_len(data, len);
 | 
			
		||||
 		memcpy(__get_dynamic_array(payload),
 | 
			
		||||
 		       data + ath10k_frm_hdr_len(data, len), __entry->len);
 | 
			
		||||
@@ -435,8 +435,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->hw_type = ar->hw_rev;
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(rxdesc), data, len);
 | 
			
		||||
@@ -472,8 +472,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->type = type;
 | 
			
		||||
 		__entry->timestamp = timestamp;
 | 
			
		||||
 		__entry->code = code;
 | 
			
		||||
@@ -505,8 +505,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(data), data, len);
 | 
			
		||||
 	),
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath11k/trace.h	2024-09-13 13:31:32.047704605 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath11k/trace.h	2024-09-13 13:37:29.026645264 +0200
 | 
			
		||||
@@ -48,8 +48,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		__entry->pktlog_checksum = pktlog_checksum;
 | 
			
		||||
 		memcpy(__get_dynamic_array(pktlog), buf, buf_len);
 | 
			
		||||
@@ -77,8 +77,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(ppdu), data, len);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -105,8 +105,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		__entry->log_type = log_type;
 | 
			
		||||
 		memcpy(__get_dynamic_array(rxdesc), data, len);
 | 
			
		||||
@@ -130,8 +130,8 @@
 | 
			
		||||
 		__vstring(msg, vaf->fmt, vaf->va)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk(
 | 
			
		||||
@@ -171,8 +171,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->id = id;
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
@@ -201,8 +201,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->id = id;
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
@@ -230,8 +230,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->level = level;
 | 
			
		||||
 		WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
 | 
			
		||||
 				       ATH11K_MSG_MAX, vaf->fmt,
 | 
			
		||||
@@ -262,10 +262,10 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
-		__assign_str(msg, msg);
 | 
			
		||||
-		__assign_str(prefix, prefix);
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
+		__assign_str(msg);
 | 
			
		||||
+		__assign_str(prefix);
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -292,8 +292,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(data), data, len);
 | 
			
		||||
 	),
 | 
			
		||||
@@ -318,8 +318,8 @@
 | 
			
		||||
 			 __field(u32, peer_ps_timestamp)
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
-	TP_fast_assign(__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		       __assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+	TP_fast_assign(__assign_str(device);
 | 
			
		||||
+		       __assign_str(driver);
 | 
			
		||||
 		       memcpy(__get_dynamic_array(peer_addr), peer_addr,
 | 
			
		||||
 			      ETH_ALEN);
 | 
			
		||||
 		       __entry->peer_ps_state = peer_ps_state;
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath12k/trace.h	2024-09-13 13:31:32.071704265 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath12k/trace.h	2024-09-13 13:38:04.682139931 +0200
 | 
			
		||||
@@ -36,8 +36,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		__entry->pktlog_checksum = pktlog_checksum;
 | 
			
		||||
 		memcpy(__get_dynamic_array(pktlog), buf, buf_len);
 | 
			
		||||
@@ -73,8 +73,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		__entry->info = ar->pdev->timestamp.info;
 | 
			
		||||
 		__entry->sync_tstmp_lo_us = ar->pdev->timestamp.sync_timestamp_hi_us;
 | 
			
		||||
@@ -117,8 +117,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ar->ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ar->ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		__entry->type = type;
 | 
			
		||||
 		__entry->info = ar->pdev->timestamp.info;
 | 
			
		||||
@@ -153,8 +153,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(device, dev_name(ab->dev));
 | 
			
		||||
-		__assign_str(driver, dev_driver_string(ab->dev));
 | 
			
		||||
+		__assign_str(device);
 | 
			
		||||
+		__assign_str(driver);
 | 
			
		||||
 		__entry->len = len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(data), data, len);
 | 
			
		||||
 	),
 | 
			
		||||
--- a/drivers/net/wireless/ath/ath6kl/trace.h	2024-09-13 13:31:32.079704151 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/ath/ath6kl/trace.h	2024-09-13 13:33:01.462437360 +0200
 | 
			
		||||
@@ -304,8 +304,8 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(msg, msg);
 | 
			
		||||
-		__assign_str(prefix, prefix);
 | 
			
		||||
+		__assign_str(msg);
 | 
			
		||||
+		__assign_str(prefix);
 | 
			
		||||
 		__entry->buf_len = buf_len;
 | 
			
		||||
 		memcpy(__get_dynamic_array(buf), buf, buf_len);
 | 
			
		||||
 	),
 | 
			
		||||
--- a/drivers/net/wireless/ath/trace.h	2024-09-13 13:31:32.043704662 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/ath/trace.h	2024-09-13 13:44:05.849032491 +0200
 | 
			
		||||
@@ -44,8 +44,8 @@
 | 
			
		||||
 	    ),
 | 
			
		||||
 
 | 
			
		||||
 	    TP_fast_assign(
 | 
			
		||||
-		    __assign_str(device, wiphy_name(wiphy));
 | 
			
		||||
-		    __assign_str(driver, KBUILD_MODNAME);
 | 
			
		||||
+		    __assign_str(device);
 | 
			
		||||
+		    __assign_str(driver);
 | 
			
		||||
 		    __assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	    ),
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h	2024-09-13 13:31:31.999705285 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h	2024-09-13 13:42:28.746405624 +0200
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
 		__vstring(msg, vaf->fmt, vaf->va)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(func, func);
 | 
			
		||||
+		__assign_str(func);
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk("%s: %s", __get_str(func), __get_str(msg))
 | 
			
		||||
@@ -57,7 +57,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
 		__entry->level = level;
 | 
			
		||||
-		__assign_str(func, func);
 | 
			
		||||
+		__assign_str(func);
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk("%s: %s", __get_str(func), __get_str(msg))
 | 
			
		||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac.h	2024-09-13 13:31:32.011705114 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac.h	2024-09-13 13:42:44.218186836 +0200
 | 
			
		||||
@@ -81,7 +81,7 @@
 | 
			
		||||
 		__field(u32, mask)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(dev, dev_name(dev));
 | 
			
		||||
+		__assign_str(dev);
 | 
			
		||||
 		__entry->in_isr = in_isr;
 | 
			
		||||
 		__entry->macintstatus = macintstatus;
 | 
			
		||||
 		__entry->mask = mask;
 | 
			
		||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h	2024-09-13 13:31:32.011705114 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h	2024-09-13 13:42:52.242073370 +0200
 | 
			
		||||
@@ -71,7 +71,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
 		__entry->level = level;
 | 
			
		||||
-		__assign_str(func, func);
 | 
			
		||||
+		__assign_str(func);
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk("%s: %s", __get_str(func), __get_str(msg))
 | 
			
		||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h	2024-09-13 13:31:32.011705114 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h	2024-09-13 13:43:12.721783766 +0200
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
 		__dynamic_array(u8, txh, txh_len)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(dev, dev_name(dev));
 | 
			
		||||
+		__assign_str(dev);
 | 
			
		||||
 		memcpy(__get_dynamic_array(txh), txh, txh_len);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk("[%s] txdesc", __get_str(dev))
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
 		__field(u16, ackphyrxsh)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(dev, dev_name(dev));
 | 
			
		||||
+		__assign_str(dev);
 | 
			
		||||
 		__entry->framelen = framelen;
 | 
			
		||||
 		__entry->frameid = frameid;
 | 
			
		||||
 		__entry->status = status;
 | 
			
		||||
@@ -85,7 +85,7 @@
 | 
			
		||||
 		__field(u16, dma_len)
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(dev, dev_name(dev));
 | 
			
		||||
+		__assign_str(dev);
 | 
			
		||||
 		__entry->max_ampdu_len = max_ampdu_len;
 | 
			
		||||
 		__entry->max_ampdu_frames = max_ampdu_frames;
 | 
			
		||||
 		__entry->ampdu_len = ampdu_len;
 | 
			
		||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h	2024-09-13 13:31:31.915706475 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h	2024-09-13 13:41:47.314991509 +0200
 | 
			
		||||
@@ -87,7 +87,7 @@
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
 #define DEV_ENTRY	__string(dev, dev_name(dev))
 | 
			
		||||
-#define DEV_ASSIGN	__assign_str(dev, dev_name(dev))
 | 
			
		||||
+#define DEV_ASSIGN	__assign_str(dev)
 | 
			
		||||
 
 | 
			
		||||
 #include "iwl-devtrace-io.h"
 | 
			
		||||
 #include "iwl-devtrace-ucode.h"
 | 
			
		||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h	2024-09-13 13:31:31.915706475 +0200
 | 
			
		||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h	2024-09-13 13:41:36.363146379 +0200
 | 
			
		||||
@@ -57,7 +57,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
 		__entry->level = level;
 | 
			
		||||
-		__assign_str(function, function);
 | 
			
		||||
+		__assign_str(function);
 | 
			
		||||
 		__assign_vstr(msg, vaf->fmt, vaf->va);
 | 
			
		||||
 	),
 | 
			
		||||
 	TP_printk("%s", __get_str(msg))
 | 
			
		||||
--- a/include/trace/events/qrtr.h	2024-09-13 13:31:32.207702337 +0200
 | 
			
		||||
+++ b/include/trace/events/qrtr.h	2024-09-13 13:39:51.068635354 +0200
 | 
			
		||||
@@ -102,7 +102,7 @@
 | 
			
		||||
 	),
 | 
			
		||||
 
 | 
			
		||||
 	TP_fast_assign(
 | 
			
		||||
-		__assign_str(ctrl_pkt_str, ctrl_pkt_str);
 | 
			
		||||
+		__assign_str(ctrl_pkt_str);
 | 
			
		||||
 		__entry->sq_node = sq_node;
 | 
			
		||||
 		__entry->sq_port = sq_port;
 | 
			
		||||
 	),
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ Signed-off-by: Jens Axboe <axboe@kernel.dk>
 | 
			
		|||
 | 
			
		||||
--- a/block/blk.h
 | 
			
		||||
+++ b/block/blk.h
 | 
			
		||||
@@ -564,6 +564,7 @@ void blk_free_ext_minor(unsigned int min
 | 
			
		||||
@@ -555,6 +555,7 @@ void blk_free_ext_minor(unsigned int min
 | 
			
		||||
 #define ADDPART_FLAG_NONE	0
 | 
			
		||||
 #define ADDPART_FLAG_RAID	1
 | 
			
		||||
 #define ADDPART_FLAG_WHOLEDISK	2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ Signed-off-by: Jens Axboe <axboe@kernel.dk>
 | 
			
		|||
 static void blk_report_disk_dead(struct gendisk *disk, bool surprise)
 | 
			
		||||
--- a/include/linux/blkdev.h
 | 
			
		||||
+++ b/include/linux/blkdev.h
 | 
			
		||||
@@ -735,6 +735,9 @@ static inline unsigned int blk_queue_dep
 | 
			
		||||
@@ -733,6 +733,9 @@ static inline unsigned int blk_queue_dep
 | 
			
		||||
 #define for_each_bio(_bio)		\
 | 
			
		||||
 	for (; _bio; _bio = _bio->bi_next)
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
From 854d71c555dfc3383c1fde7d9989b6046e21093d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 9 Oct 2024 07:48:05 +0200
 | 
			
		||||
Subject: [PATCH] r8169: remove original workaround for RTL8125 broken rx issue
 | 
			
		||||
 | 
			
		||||
Now that we have b9c7ac4fe22c ("r8169: disable ALDPS per default for
 | 
			
		||||
RTL8125"), the first attempt to fix the issue shouldn't be needed
 | 
			
		||||
any longer. So let's effectively revert 621735f59064 ("r8169: fix
 | 
			
		||||
rare issue with broken rx after link-down on RTL8125") and see
 | 
			
		||||
whether anybody complains.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/382d8c88-cbce-400f-ad62-fda0181c7e38@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 4 ----
 | 
			
		||||
 1 file changed, 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -4777,11 +4777,7 @@ static void r8169_phylink_handler(struct
 | 
			
		||||
 	if (netif_carrier_ok(ndev)) {
 | 
			
		||||
 		rtl_link_chg_patch(tp);
 | 
			
		||||
 		pm_request_resume(d);
 | 
			
		||||
-		netif_wake_queue(tp->dev);
 | 
			
		||||
 	} else {
 | 
			
		||||
-		/* In few cases rx is broken after link-down otherwise */
 | 
			
		||||
-		if (rtl_is_8125(tp))
 | 
			
		||||
-			rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE);
 | 
			
		||||
 		pm_runtime_idle(d);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
From b8bf38440ba94e8ed8e2ae55c5dfb0276d30e843 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 10 Oct 2024 12:58:02 +0200
 | 
			
		||||
Subject: [PATCH] r8169: enable SG/TSO on selected chip versions per default
 | 
			
		||||
 | 
			
		||||
Due to problem reports in the past SG and TSO/TSO6 are disabled per
 | 
			
		||||
default. It's not fully clear which chip versions are affected, so we
 | 
			
		||||
may impact also users of unaffected chip versions, unless they know
 | 
			
		||||
how to use ethtool for enabling SG/TSO/TSO6.
 | 
			
		||||
Vendor drivers r8168/r8125 enable SG/TSO/TSO6 for selected chip
 | 
			
		||||
versions per default, I'd interpret this as confirmation that these
 | 
			
		||||
chip versions are unaffected. So let's do the same here.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 16 +++++++++++-----
 | 
			
		||||
 1 file changed, 11 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -5489,11 +5489,6 @@ static int rtl_init_one(struct pci_dev *
 | 
			
		||||
 
 | 
			
		||||
 	dev->features |= dev->hw_features;
 | 
			
		||||
 
 | 
			
		||||
-	/* There has been a number of reports that using SG/TSO results in
 | 
			
		||||
-	 * tx timeouts. However for a lot of people SG/TSO works fine.
 | 
			
		||||
-	 * Therefore disable both features by default, but allow users to
 | 
			
		||||
-	 * enable them. Use at own risk!
 | 
			
		||||
-	 */
 | 
			
		||||
 	if (rtl_chip_supports_csum_v2(tp)) {
 | 
			
		||||
 		dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6;
 | 
			
		||||
 		netif_set_tso_max_size(dev, RTL_GSO_MAX_SIZE_V2);
 | 
			
		||||
@@ -5504,6 +5499,17 @@ static int rtl_init_one(struct pci_dev *
 | 
			
		||||
 		netif_set_tso_max_segs(dev, RTL_GSO_MAX_SEGS_V1);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* There has been a number of reports that using SG/TSO results in
 | 
			
		||||
+	 * tx timeouts. However for a lot of people SG/TSO works fine.
 | 
			
		||||
+	 * It's not fully clear which chip versions are affected. Vendor
 | 
			
		||||
+	 * drivers enable SG/TSO for certain chip versions per default,
 | 
			
		||||
+	 * let's mimic this here. On other chip versions users can
 | 
			
		||||
+	 * use ethtool to enable SG/TSO, use at own risk!
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (tp->mac_version >= RTL_GIGA_MAC_VER_46 &&
 | 
			
		||||
+	    tp->mac_version != RTL_GIGA_MAC_VER_61)
 | 
			
		||||
+		dev->features |= dev->hw_features;
 | 
			
		||||
+
 | 
			
		||||
 	dev->hw_features |= NETIF_F_RXALL;
 | 
			
		||||
 	dev->hw_features |= NETIF_F_RXFCS;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
From e3fc5139bd8ffaa1498adc21be4e8ecbc6aed508 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Sun, 13 Oct 2024 11:17:39 +0200
 | 
			
		||||
Subject: [PATCH] r8169: implement additional ethtool stats ops
 | 
			
		||||
 | 
			
		||||
This adds support for ethtool standard statistics, and makes use of the
 | 
			
		||||
extended hardware statistics being available from RTl8125.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/58e0da73-a7dd-4be3-82ae-d5b3f9069bde@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 82 +++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 82 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -2160,6 +2160,19 @@ static void rtl8169_get_ringparam(struct
 | 
			
		||||
 	data->tx_pending = NUM_TX_DESC;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8169_get_pause_stats(struct net_device *dev,
 | 
			
		||||
+				    struct ethtool_pause_stats *pause_stats)
 | 
			
		||||
+{
 | 
			
		||||
+	struct rtl8169_private *tp = netdev_priv(dev);
 | 
			
		||||
+
 | 
			
		||||
+	if (!rtl_is_8125(tp))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	rtl8169_update_counters(tp);
 | 
			
		||||
+	pause_stats->tx_pause_frames = le32_to_cpu(tp->counters->tx_pause_on);
 | 
			
		||||
+	pause_stats->rx_pause_frames = le32_to_cpu(tp->counters->rx_pause_on);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void rtl8169_get_pauseparam(struct net_device *dev,
 | 
			
		||||
 				   struct ethtool_pauseparam *data)
 | 
			
		||||
 {
 | 
			
		||||
@@ -2186,6 +2199,69 @@ static int rtl8169_set_pauseparam(struct
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8169_get_eth_mac_stats(struct net_device *dev,
 | 
			
		||||
+				      struct ethtool_eth_mac_stats *mac_stats)
 | 
			
		||||
+{
 | 
			
		||||
+	struct rtl8169_private *tp = netdev_priv(dev);
 | 
			
		||||
+
 | 
			
		||||
+	rtl8169_update_counters(tp);
 | 
			
		||||
+
 | 
			
		||||
+	mac_stats->FramesTransmittedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->tx_packets);
 | 
			
		||||
+	mac_stats->SingleCollisionFrames =
 | 
			
		||||
+		le32_to_cpu(tp->counters->tx_one_collision);
 | 
			
		||||
+	mac_stats->MultipleCollisionFrames =
 | 
			
		||||
+		le32_to_cpu(tp->counters->tx_multi_collision);
 | 
			
		||||
+	mac_stats->FramesReceivedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->rx_packets);
 | 
			
		||||
+	mac_stats->AlignmentErrors =
 | 
			
		||||
+		le16_to_cpu(tp->counters->align_errors);
 | 
			
		||||
+	mac_stats->FramesLostDueToIntMACXmitError =
 | 
			
		||||
+		le64_to_cpu(tp->counters->tx_errors);
 | 
			
		||||
+	mac_stats->BroadcastFramesReceivedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->rx_broadcast);
 | 
			
		||||
+	mac_stats->MulticastFramesReceivedOK =
 | 
			
		||||
+		le32_to_cpu(tp->counters->rx_multicast);
 | 
			
		||||
+
 | 
			
		||||
+	if (!rtl_is_8125(tp))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	mac_stats->AlignmentErrors =
 | 
			
		||||
+		le32_to_cpu(tp->counters->align_errors32);
 | 
			
		||||
+	mac_stats->OctetsTransmittedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->tx_octets);
 | 
			
		||||
+	mac_stats->LateCollisions =
 | 
			
		||||
+		le32_to_cpu(tp->counters->tx_late_collision);
 | 
			
		||||
+	mac_stats->FramesAbortedDueToXSColls =
 | 
			
		||||
+		le32_to_cpu(tp->counters->tx_aborted32);
 | 
			
		||||
+	mac_stats->OctetsReceivedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->rx_octets);
 | 
			
		||||
+	mac_stats->FramesLostDueToIntMACRcvError =
 | 
			
		||||
+		le32_to_cpu(tp->counters->rx_mac_error);
 | 
			
		||||
+	mac_stats->MulticastFramesXmittedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->tx_multicast64);
 | 
			
		||||
+	mac_stats->BroadcastFramesXmittedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->tx_broadcast64);
 | 
			
		||||
+	mac_stats->MulticastFramesReceivedOK =
 | 
			
		||||
+		le64_to_cpu(tp->counters->rx_multicast64);
 | 
			
		||||
+	 mac_stats->FrameTooLongErrors =
 | 
			
		||||
+		le32_to_cpu(tp->counters->rx_frame_too_long);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void rtl8169_get_eth_ctrl_stats(struct net_device *dev,
 | 
			
		||||
+				       struct ethtool_eth_ctrl_stats *ctrl_stats)
 | 
			
		||||
+{
 | 
			
		||||
+	struct rtl8169_private *tp = netdev_priv(dev);
 | 
			
		||||
+
 | 
			
		||||
+	if (!rtl_is_8125(tp))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	rtl8169_update_counters(tp);
 | 
			
		||||
+
 | 
			
		||||
+	ctrl_stats->UnsupportedOpcodesReceived =
 | 
			
		||||
+		le32_to_cpu(tp->counters->rx_unknown_opcode);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static const struct ethtool_ops rtl8169_ethtool_ops = {
 | 
			
		||||
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 | 
			
		||||
 				     ETHTOOL_COALESCE_MAX_FRAMES,
 | 
			
		||||
@@ -2207,8 +2283,11 @@ static const struct ethtool_ops rtl8169_
 | 
			
		||||
 	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
 | 
			
		||||
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 | 
			
		||||
 	.get_ringparam		= rtl8169_get_ringparam,
 | 
			
		||||
+	.get_pause_stats	= rtl8169_get_pause_stats,
 | 
			
		||||
 	.get_pauseparam		= rtl8169_get_pauseparam,
 | 
			
		||||
 	.set_pauseparam		= rtl8169_set_pauseparam,
 | 
			
		||||
+	.get_eth_mac_stats	= rtl8169_get_eth_mac_stats,
 | 
			
		||||
+	.get_eth_ctrl_stats	= rtl8169_get_eth_ctrl_stats,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
 | 
			
		||||
@@ -3893,6 +3972,9 @@ static void rtl_hw_start_8125(struct rtl
 | 
			
		||||
 		break;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* enable extended tally counter */
 | 
			
		||||
+	r8168_mac_ocp_modify(tp, 0xea84, 0, BIT(1) | BIT(0));
 | 
			
		||||
+
 | 
			
		||||
 	rtl_hw_config(tp);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
From ac48430368c1a4f4e6c2fa92243b4b93fd25bee4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 16 Oct 2024 22:05:57 +0200
 | 
			
		||||
Subject: [PATCH] r8169: don't take RTNL lock in rtl_task()
 | 
			
		||||
 | 
			
		||||
There's not really a benefit here in taking the RTNL lock. The task
 | 
			
		||||
handler does exception handling only, so we're in trouble anyway when
 | 
			
		||||
we come here, and there's no need to protect against e.g. a parallel
 | 
			
		||||
ethtool call.
 | 
			
		||||
A benefit of removing the RTNL lock here is that we now can
 | 
			
		||||
synchronously cancel the workqueue from a context holding the RTNL mutex.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 8 ++------
 | 
			
		||||
 1 file changed, 2 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -4800,10 +4800,8 @@ static void rtl_task(struct work_struct
 | 
			
		||||
 		container_of(work, struct rtl8169_private, wk.work);
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
-	rtnl_lock();
 | 
			
		||||
-
 | 
			
		||||
 	if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
 | 
			
		||||
-		goto out_unlock;
 | 
			
		||||
+		return;
 | 
			
		||||
 
 | 
			
		||||
 	if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
 | 
			
		||||
 		/* if chip isn't accessible, reset bus to revive it */
 | 
			
		||||
@@ -4812,7 +4810,7 @@ static void rtl_task(struct work_struct
 | 
			
		||||
 			if (ret < 0) {
 | 
			
		||||
 				netdev_err(tp->dev, "Can't reset secondary PCI bus, detach NIC\n");
 | 
			
		||||
 				netif_device_detach(tp->dev);
 | 
			
		||||
-				goto out_unlock;
 | 
			
		||||
+				return;
 | 
			
		||||
 			}
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
@@ -4831,8 +4829,6 @@ reset:
 | 
			
		||||
 	} else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
 | 
			
		||||
 		rtl_reset_work(tp);
 | 
			
		||||
 	}
 | 
			
		||||
-out_unlock:
 | 
			
		||||
-	rtnl_unlock();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int rtl8169_poll(struct napi_struct *napi, int budget)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
From 1c105bacb160b5918e917ab811552b7be69fc69c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 16 Oct 2024 22:29:39 +0200
 | 
			
		||||
Subject: [PATCH] r8169: avoid duplicated messages if loading firmware fails
 | 
			
		||||
 and switch to warn level
 | 
			
		||||
 | 
			
		||||
In case of a problem with firmware loading we inform at the driver level,
 | 
			
		||||
in addition the firmware load code itself issues warnings. Therefore
 | 
			
		||||
switch to firmware_request_nowarn() to avoid duplicated error messages.
 | 
			
		||||
In addition switch to warn level because the firmware is optional and
 | 
			
		||||
typically just fixes compatibility issues.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Message-ID: <d9c5094c-89a6-40e2-b5fe-8df7df4624ef@gmail.com>
 | 
			
		||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_firmware.c | 6 +++---
 | 
			
		||||
 1 file changed, 3 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_firmware.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_firmware.c
 | 
			
		||||
@@ -215,7 +215,7 @@ int rtl_fw_request_firmware(struct rtl_f
 | 
			
		||||
 {
 | 
			
		||||
 	int rc;
 | 
			
		||||
 
 | 
			
		||||
-	rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
 | 
			
		||||
+	rc = firmware_request_nowarn(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
 | 
			
		||||
 	if (rc < 0)
 | 
			
		||||
 		goto out;
 | 
			
		||||
 
 | 
			
		||||
@@ -227,7 +227,7 @@ int rtl_fw_request_firmware(struct rtl_f
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 out:
 | 
			
		||||
-	dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
 | 
			
		||||
-		rtl_fw->fw_name, rc);
 | 
			
		||||
+	dev_warn(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
 | 
			
		||||
+		 rtl_fw->fw_name, rc);
 | 
			
		||||
 	return rc;
 | 
			
		||||
 }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
From d64113c6bb5ea5a70b7c9c3a6bcadef307638187 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 16 Oct 2024 22:31:10 +0200
 | 
			
		||||
Subject: [PATCH] r8169: remove rtl_dash_loop_wait_high/low
 | 
			
		||||
 | 
			
		||||
Remove rtl_dash_loop_wait_high/low to simplify the code.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Message-ID: <fb8c490c-2d92-48f5-8bbf-1fc1f2ee1649@gmail.com>
 | 
			
		||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 35 ++++++-----------------
 | 
			
		||||
 1 file changed, 8 insertions(+), 27 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -1346,40 +1346,19 @@ static void rtl8168ep_stop_cmac(struct r
 | 
			
		||||
 	RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void rtl_dash_loop_wait(struct rtl8169_private *tp,
 | 
			
		||||
-			       const struct rtl_cond *c,
 | 
			
		||||
-			       unsigned long usecs, int n, bool high)
 | 
			
		||||
-{
 | 
			
		||||
-	if (!tp->dash_enabled)
 | 
			
		||||
-		return;
 | 
			
		||||
-	rtl_loop_wait(tp, c, usecs, n, high);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void rtl_dash_loop_wait_high(struct rtl8169_private *tp,
 | 
			
		||||
-				    const struct rtl_cond *c,
 | 
			
		||||
-				    unsigned long d, int n)
 | 
			
		||||
-{
 | 
			
		||||
-	rtl_dash_loop_wait(tp, c, d, n, true);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void rtl_dash_loop_wait_low(struct rtl8169_private *tp,
 | 
			
		||||
-				   const struct rtl_cond *c,
 | 
			
		||||
-				   unsigned long d, int n)
 | 
			
		||||
-{
 | 
			
		||||
-	rtl_dash_loop_wait(tp, c, d, n, false);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 static void rtl8168dp_driver_start(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START);
 | 
			
		||||
-	rtl_dash_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
 | 
			
		||||
+	if (tp->dash_enabled)
 | 
			
		||||
+		rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8168ep_driver_start(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
 | 
			
		||||
 	r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
 | 
			
		||||
-	rtl_dash_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
 | 
			
		||||
+	if (tp->dash_enabled)
 | 
			
		||||
+		rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8168_driver_start(struct rtl8169_private *tp)
 | 
			
		||||
@@ -1393,7 +1372,8 @@ static void rtl8168_driver_start(struct
 | 
			
		||||
 static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
 | 
			
		||||
-	rtl_dash_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
 | 
			
		||||
+	if (tp->dash_enabled)
 | 
			
		||||
+		rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
 | 
			
		||||
@@ -1401,7 +1381,8 @@ static void rtl8168ep_driver_stop(struct
 | 
			
		||||
 	rtl8168ep_stop_cmac(tp);
 | 
			
		||||
 	r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
 | 
			
		||||
 	r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
 | 
			
		||||
-	rtl_dash_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
 | 
			
		||||
+	if (tp->dash_enabled)
 | 
			
		||||
+		rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8168_driver_stop(struct rtl8169_private *tp)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
From c4e64095c00cb2de413cd6b90be047c273bcd491 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 17 Oct 2024 22:27:44 +0200
 | 
			
		||||
Subject: [PATCH] r8169: enable EEE at 2.5G per default on RTL8125B
 | 
			
		||||
 | 
			
		||||
Register a6d/12 is shadowing register MDIO_AN_EEE_ADV2. So this line
 | 
			
		||||
disables advertisement of EEE at 2.5G. Latest vendor driver r8125
 | 
			
		||||
doesn't do this (any longer?), so this mode seems to be safe.
 | 
			
		||||
EEE saves quite some energy, therefore enable this mode per default.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Message-ID: <95dd5a0c-09ea-4847-94d9-b7aa3063e8ff@gmail.com>
 | 
			
		||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_phy_config.c | 1 -
 | 
			
		||||
 1 file changed, 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -99,7 +99,6 @@ static void rtl8125a_config_eee_phy(stru
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8125b_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
 | 
			
		||||
 	phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
 | 
			
		||||
 	phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
 | 
			
		||||
 	phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,143 @@
 | 
			
		|||
From f75d1fbe7809bc5ed134204b920fd9e2fc5db1df Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 24 Oct 2024 22:42:33 +0200
 | 
			
		||||
Subject: [PATCH] r8169: add support for RTL8125D
 | 
			
		||||
 | 
			
		||||
This adds support for new chip version RTL8125D, which can be found on
 | 
			
		||||
boards like Gigabyte X870E AORUS ELITE WIFI7. Firmware rtl8125d-1.fw
 | 
			
		||||
for this chip version is available in linux-firmware already.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/d0306912-e88e-4c25-8b5d-545ae8834c0c@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169.h          |  1 +
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c     | 23 +++++++++++++------
 | 
			
		||||
 .../net/ethernet/realtek/r8169_phy_config.c   | 10 ++++++++
 | 
			
		||||
 3 files changed, 27 insertions(+), 7 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
@@ -68,6 +68,7 @@ enum mac_version {
 | 
			
		||||
 	/* support for RTL_GIGA_MAC_VER_60 has been removed */
 | 
			
		||||
 	RTL_GIGA_MAC_VER_61,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_63,
 | 
			
		||||
+	RTL_GIGA_MAC_VER_64,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_65,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_66,
 | 
			
		||||
 	RTL_GIGA_MAC_NONE
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -55,6 +55,7 @@
 | 
			
		||||
 #define FIRMWARE_8107E_2	"rtl_nic/rtl8107e-2.fw"
 | 
			
		||||
 #define FIRMWARE_8125A_3	"rtl_nic/rtl8125a-3.fw"
 | 
			
		||||
 #define FIRMWARE_8125B_2	"rtl_nic/rtl8125b-2.fw"
 | 
			
		||||
+#define FIRMWARE_8125D_1	"rtl_nic/rtl8125d-1.fw"
 | 
			
		||||
 #define FIRMWARE_8126A_2	"rtl_nic/rtl8126a-2.fw"
 | 
			
		||||
 #define FIRMWARE_8126A_3	"rtl_nic/rtl8126a-3.fw"
 | 
			
		||||
 
 | 
			
		||||
@@ -138,6 +139,7 @@ static const struct {
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_61] = {"RTL8125A",		FIRMWARE_8125A_3},
 | 
			
		||||
 	/* reserve 62 for CFG_METHOD_4 in the vendor driver */
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_63] = {"RTL8125B",		FIRMWARE_8125B_2},
 | 
			
		||||
+	[RTL_GIGA_MAC_VER_64] = {"RTL8125D",		FIRMWARE_8125D_1},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_65] = {"RTL8126A",		FIRMWARE_8126A_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_66] = {"RTL8126A",		FIRMWARE_8126A_3},
 | 
			
		||||
 };
 | 
			
		||||
@@ -707,6 +709,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8107E_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125A_3);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125B_2);
 | 
			
		||||
+MODULE_FIRMWARE(FIRMWARE_8125D_1);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8126A_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8126A_3);
 | 
			
		||||
 
 | 
			
		||||
@@ -2079,10 +2082,7 @@ static void rtl_set_eee_txidle_timer(str
 | 
			
		||||
 		tp->tx_lpi_timer = timer_val;
 | 
			
		||||
 		r8168_mac_ocp_write(tp, 0xe048, timer_val);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_61:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_63:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
 		tp->tx_lpi_timer = timer_val;
 | 
			
		||||
 		RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -2293,6 +2293,9 @@ static enum mac_version rtl8169_get_mac_
 | 
			
		||||
 		{ 0x7cf, 0x64a,	RTL_GIGA_MAC_VER_66 },
 | 
			
		||||
 		{ 0x7cf, 0x649,	RTL_GIGA_MAC_VER_65 },
 | 
			
		||||
 
 | 
			
		||||
+		/* 8125D family. */
 | 
			
		||||
+		{ 0x7cf, 0x688,	RTL_GIGA_MAC_VER_64 },
 | 
			
		||||
+
 | 
			
		||||
 		/* 8125B family. */
 | 
			
		||||
 		{ 0x7cf, 0x641,	RTL_GIGA_MAC_VER_63 },
 | 
			
		||||
 
 | 
			
		||||
@@ -2560,9 +2563,7 @@ static void rtl_init_rxcfg(struct rtl816
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_61:
 | 
			
		||||
 		RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_63:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
 		RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
 | 
			
		||||
 			RX_PAUSE_SLOT_ON);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -3874,6 +3875,12 @@ static void rtl_hw_start_8125b(struct rt
 | 
			
		||||
 	rtl_hw_start_8125_common(tp);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl_hw_start_8125d(struct rtl8169_private *tp)
 | 
			
		||||
+{
 | 
			
		||||
+	rtl_set_def_aspm_entry_latency(tp);
 | 
			
		||||
+	rtl_hw_start_8125_common(tp);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void rtl_hw_start_8126a(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	rtl_set_def_aspm_entry_latency(tp);
 | 
			
		||||
@@ -3922,6 +3929,7 @@ static void rtl_hw_config(struct rtl8169
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a,
 | 
			
		||||
 	};
 | 
			
		||||
@@ -3939,6 +3947,7 @@ static void rtl_hw_start_8125(struct rtl
 | 
			
		||||
 	/* disable interrupt coalescing */
 | 
			
		||||
 	switch (tp->mac_version) {
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_61:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_64:
 | 
			
		||||
 		for (i = 0xa00; i < 0xb00; i += 4)
 | 
			
		||||
 			RTL_W32(tp, i, 0);
 | 
			
		||||
 		break;
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -1103,6 +1103,15 @@ static void rtl8125b_hw_phy_config(struc
 | 
			
		||||
 	rtl8125b_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8125d_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
+				   struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	r8169_apply_firmware(tp);
 | 
			
		||||
+	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
+	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
+	rtl8125b_config_eee_phy(phydev);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
 				   struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1159,6 +1168,7 @@ void r8169_hw_phy_config(struct rtl8169_
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_66] = rtl8126a_hw_phy_config,
 | 
			
		||||
 	};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
From b8bd8c44a266c9a7dcb907eab10fbb119e3f6494 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 24 Oct 2024 22:48:59 +0200
 | 
			
		||||
Subject: [PATCH] r8169: fix inconsistent indenting in
 | 
			
		||||
 rtl8169_get_eth_mac_stats
 | 
			
		||||
 | 
			
		||||
This fixes an inconsistent indenting introduced with e3fc5139bd8f
 | 
			
		||||
("r8169: implement additional ethtool stats ops").
 | 
			
		||||
 | 
			
		||||
Reported-by: kernel test robot <lkp@intel.com>
 | 
			
		||||
Closes: https://lore.kernel.org/oe-kbuild-all/202410220413.1gAxIJ4t-lkp@intel.com/
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/20fd6f39-3c1b-4af0-9adc-7d1f49728fad@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -2225,7 +2225,7 @@ static void rtl8169_get_eth_mac_stats(st
 | 
			
		||||
 		le64_to_cpu(tp->counters->tx_broadcast64);
 | 
			
		||||
 	mac_stats->MulticastFramesReceivedOK =
 | 
			
		||||
 		le64_to_cpu(tp->counters->rx_multicast64);
 | 
			
		||||
-	 mac_stats->FrameTooLongErrors =
 | 
			
		||||
+	mac_stats->FrameTooLongErrors =
 | 
			
		||||
 		le32_to_cpu(tp->counters->rx_frame_too_long);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
From eb90f876b7961d702d7fc549e14614860f531e60 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 31 Oct 2024 22:42:52 +0100
 | 
			
		||||
Subject: [PATCH] r8169: align RTL8125 EEE config with vendor driver
 | 
			
		||||
 | 
			
		||||
Align the EEE config for RTL8125A/RTL8125B with vendor driver r8125.
 | 
			
		||||
This should help to avoid compatibility issues.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/044c925e-8669-4b98-87df-95b4056f4f5f@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 .../net/ethernet/realtek/r8169_phy_config.c    | 18 ++++++++++++------
 | 
			
		||||
 1 file changed, 12 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -89,19 +89,25 @@ static void rtl8168h_config_eee_phy(stru
 | 
			
		||||
 	phy_modify_paged(phydev, 0xa42, 0x14, 0x0000, 0x0080);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void rtl8125a_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
+static void rtl8125_common_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
-	rtl8168h_config_eee_phy(phydev);
 | 
			
		||||
+	phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
 | 
			
		||||
+	phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
 | 
			
		||||
+	phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
 | 
			
		||||
+}
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8125a_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	rtl8168g_config_eee_phy(phydev);
 | 
			
		||||
+	/* disable EEE at 2.5Gbps */
 | 
			
		||||
 	phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
 | 
			
		||||
+	rtl8125_common_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8125b_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000);
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000);
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
 | 
			
		||||
+	rtl8168g_config_eee_phy(phydev);
 | 
			
		||||
+	rtl8125_common_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8169s_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
From 4af2f60bf7378bd5c92b15a528d8c6c7d02bed6c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 31 Oct 2024 22:43:45 +0100
 | 
			
		||||
Subject: [PATCH] r8169: align RTL8125/RTL8126 PHY config with vendor driver
 | 
			
		||||
 | 
			
		||||
This aligns some parameters with vendor driver r8125/r8126 to avoid
 | 
			
		||||
compatibility issues. Note that for RTL8125B there's no functional
 | 
			
		||||
change, just the open-coded version of the function is replaced.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/a8a9d896-fbe6-41f2-bf87-666567d3cdb3@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_phy_config.c | 6 +++++-
 | 
			
		||||
 1 file changed, 5 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -1073,8 +1073,8 @@ static void rtl8125b_hw_phy_config(struc
 | 
			
		||||
 				   struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	r8169_apply_firmware(tp);
 | 
			
		||||
+	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
 
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800);
 | 
			
		||||
 	phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090);
 | 
			
		||||
 	phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001);
 | 
			
		||||
 
 | 
			
		||||
@@ -1113,6 +1113,7 @@ static void rtl8125d_hw_phy_config(struc
 | 
			
		||||
 				   struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	r8169_apply_firmware(tp);
 | 
			
		||||
+	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
 	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
 	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
 	rtl8125b_config_eee_phy(phydev);
 | 
			
		||||
@@ -1122,6 +1123,9 @@ static void rtl8126a_hw_phy_config(struc
 | 
			
		||||
 				   struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	r8169_apply_firmware(tp);
 | 
			
		||||
+	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
+	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
+	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
From a3d8520e6a19ab018da6c7fc22512c913697a829 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 31 Oct 2024 22:44:36 +0100
 | 
			
		||||
Subject: [PATCH] r8169: align RTL8126 EEE config with vendor driver
 | 
			
		||||
 | 
			
		||||
Align the EEE config for RTL8126A with vendor driver r8126 to avoid
 | 
			
		||||
compatibility issues.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/71e4859e-4cd0-4b6b-b7fa-621d7721992f@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_phy_config.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -1126,6 +1126,7 @@ static void rtl8126a_hw_phy_config(struc
 | 
			
		||||
 	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
 	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
 	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
+	rtl8125_common_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
From 2cd02f2fdd8a92e5b6b85ff64eab0fc549b30c07 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Sat, 2 Nov 2024 14:49:01 +0100
 | 
			
		||||
Subject: [PATCH] r8169: improve initialization of RSS registers on
 | 
			
		||||
 RTL8125/RTL8126
 | 
			
		||||
 | 
			
		||||
Replace the register addresses with the names used in r8125/r8126
 | 
			
		||||
vendor driver, and consider that RSS_CTRL_8125 is a 32 bit register.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/3bf2f340-b369-4174-97bf-fd38d4217492@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 6 ++++--
 | 
			
		||||
 1 file changed, 4 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -346,6 +346,8 @@ enum rtl8125_registers {
 | 
			
		||||
 	TxPoll_8125		= 0x90,
 | 
			
		||||
 	LEDSEL3			= 0x96,
 | 
			
		||||
 	MAC0_BKP		= 0x19e0,
 | 
			
		||||
+	RSS_CTRL_8125		= 0x4500,
 | 
			
		||||
+	Q_NUM_CTRL_8125		= 0x4800,
 | 
			
		||||
 	EEE_TXIDLE_TIMER_8125	= 0x6048,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -3768,8 +3770,8 @@ static void rtl_hw_start_8125_common(str
 | 
			
		||||
 	rtl_pcie_state_l2l3_disable(tp);
 | 
			
		||||
 
 | 
			
		||||
 	RTL_W16(tp, 0x382, 0x221b);
 | 
			
		||||
-	RTL_W8(tp, 0x4500, 0);
 | 
			
		||||
-	RTL_W16(tp, 0x4800, 0);
 | 
			
		||||
+	RTL_W32(tp, RSS_CTRL_8125, 0);
 | 
			
		||||
+	RTL_W16(tp, Q_NUM_CTRL_8125, 0);
 | 
			
		||||
 
 | 
			
		||||
 	/* disable UPS */
 | 
			
		||||
 	r8168_mac_ocp_modify(tp, 0xd40a, 0x0010, 0x0000);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,113 @@
 | 
			
		|||
From 83cb4b470c66b37b19a347a35cea01e0cbdd258d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Mon, 4 Nov 2024 23:16:20 +0100
 | 
			
		||||
Subject: [PATCH] r8169: remove leftover locks after reverted change
 | 
			
		||||
 | 
			
		||||
After e31a9fedc7d8 ("Revert "r8169: disable ASPM during NAPI poll"")
 | 
			
		||||
these locks aren't needed any longer.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/680f2606-ac7d-4ced-8694-e5033855da9b@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 29 ++---------------------
 | 
			
		||||
 1 file changed, 2 insertions(+), 27 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -662,13 +662,9 @@ struct rtl8169_private {
 | 
			
		||||
 		struct work_struct work;
 | 
			
		||||
 	} wk;
 | 
			
		||||
 
 | 
			
		||||
-	raw_spinlock_t config25_lock;
 | 
			
		||||
 	raw_spinlock_t mac_ocp_lock;
 | 
			
		||||
 	struct mutex led_lock;	/* serialize LED ctrl RMW access */
 | 
			
		||||
 
 | 
			
		||||
-	raw_spinlock_t cfg9346_usage_lock;
 | 
			
		||||
-	int cfg9346_usage_count;
 | 
			
		||||
-
 | 
			
		||||
 	unsigned supports_gmii:1;
 | 
			
		||||
 	unsigned aspm_manageable:1;
 | 
			
		||||
 	unsigned dash_enabled:1;
 | 
			
		||||
@@ -722,22 +718,12 @@ static inline struct device *tp_to_dev(s
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_lock_config_regs(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
-	unsigned long flags;
 | 
			
		||||
-
 | 
			
		||||
-	raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags);
 | 
			
		||||
-	if (!--tp->cfg9346_usage_count)
 | 
			
		||||
-		RTL_W8(tp, Cfg9346, Cfg9346_Lock);
 | 
			
		||||
-	raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags);
 | 
			
		||||
+	RTL_W8(tp, Cfg9346, Cfg9346_Lock);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_unlock_config_regs(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
-	unsigned long flags;
 | 
			
		||||
-
 | 
			
		||||
-	raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags);
 | 
			
		||||
-	if (!tp->cfg9346_usage_count++)
 | 
			
		||||
-		RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
 | 
			
		||||
-	raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags);
 | 
			
		||||
+	RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_pci_commit(struct rtl8169_private *tp)
 | 
			
		||||
@@ -748,24 +734,18 @@ static void rtl_pci_commit(struct rtl816
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set)
 | 
			
		||||
 {
 | 
			
		||||
-	unsigned long flags;
 | 
			
		||||
 	u8 val;
 | 
			
		||||
 
 | 
			
		||||
-	raw_spin_lock_irqsave(&tp->config25_lock, flags);
 | 
			
		||||
 	val = RTL_R8(tp, Config2);
 | 
			
		||||
 	RTL_W8(tp, Config2, (val & ~clear) | set);
 | 
			
		||||
-	raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set)
 | 
			
		||||
 {
 | 
			
		||||
-	unsigned long flags;
 | 
			
		||||
 	u8 val;
 | 
			
		||||
 
 | 
			
		||||
-	raw_spin_lock_irqsave(&tp->config25_lock, flags);
 | 
			
		||||
 	val = RTL_R8(tp, Config5);
 | 
			
		||||
 	RTL_W8(tp, Config5, (val & ~clear) | set);
 | 
			
		||||
-	raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static bool rtl_is_8125(struct rtl8169_private *tp)
 | 
			
		||||
@@ -1571,7 +1551,6 @@ static void __rtl8169_set_wol(struct rtl
 | 
			
		||||
 		{ WAKE_MAGIC, Config3, MagicPacket }
 | 
			
		||||
 	};
 | 
			
		||||
 	unsigned int i, tmp = ARRAY_SIZE(cfg);
 | 
			
		||||
-	unsigned long flags;
 | 
			
		||||
 	u8 options;
 | 
			
		||||
 
 | 
			
		||||
 	rtl_unlock_config_regs(tp);
 | 
			
		||||
@@ -1590,14 +1569,12 @@ static void __rtl8169_set_wol(struct rtl
 | 
			
		||||
 			r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	raw_spin_lock_irqsave(&tp->config25_lock, flags);
 | 
			
		||||
 	for (i = 0; i < tmp; i++) {
 | 
			
		||||
 		options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
 | 
			
		||||
 		if (wolopts & cfg[i].opt)
 | 
			
		||||
 			options |= cfg[i].mask;
 | 
			
		||||
 		RTL_W8(tp, cfg[i].reg, options);
 | 
			
		||||
 	}
 | 
			
		||||
-	raw_spin_unlock_irqrestore(&tp->config25_lock, flags);
 | 
			
		||||
 
 | 
			
		||||
 	switch (tp->mac_version) {
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
 | 
			
		||||
@@ -5458,8 +5435,6 @@ static int rtl_init_one(struct pci_dev *
 | 
			
		||||
 	tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
 | 
			
		||||
 	tp->ocp_base = OCP_STD_PHY_BASE;
 | 
			
		||||
 
 | 
			
		||||
-	raw_spin_lock_init(&tp->cfg9346_usage_lock);
 | 
			
		||||
-	raw_spin_lock_init(&tp->config25_lock);
 | 
			
		||||
 	raw_spin_lock_init(&tp->mac_ocp_lock);
 | 
			
		||||
 	mutex_init(&tp->led_lock);
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,108 @@
 | 
			
		|||
From c507e96b5763b36b63ad50ad804341f72ea000e4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 6 Nov 2024 17:55:45 +0100
 | 
			
		||||
Subject: [PATCH] r8169: improve __rtl8169_set_wol
 | 
			
		||||
 | 
			
		||||
Add helper r8169_mod_reg8_cond() what allows to significantly simplify
 | 
			
		||||
__rtl8169_set_wol().
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/697b197a-8eac-40c6-8847-27093cacec36@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 55 ++++++++++-------------
 | 
			
		||||
 1 file changed, 24 insertions(+), 31 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -748,6 +748,20 @@ static void rtl_mod_config5(struct rtl81
 | 
			
		||||
 	RTL_W8(tp, Config5, (val & ~clear) | set);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void r8169_mod_reg8_cond(struct rtl8169_private *tp, int reg,
 | 
			
		||||
+				u8 bits, bool cond)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 val, old_val;
 | 
			
		||||
+
 | 
			
		||||
+	old_val = RTL_R8(tp, reg);
 | 
			
		||||
+	if (cond)
 | 
			
		||||
+		val = old_val | bits;
 | 
			
		||||
+	else
 | 
			
		||||
+		val = old_val & ~bits;
 | 
			
		||||
+	if (val != old_val)
 | 
			
		||||
+		RTL_W8(tp, reg, val);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static bool rtl_is_8125(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	return tp->mac_version >= RTL_GIGA_MAC_VER_61;
 | 
			
		||||
@@ -1538,58 +1552,37 @@ static void rtl8169_get_wol(struct net_d
 | 
			
		||||
 
 | 
			
		||||
 static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
 | 
			
		||||
 {
 | 
			
		||||
-	static const struct {
 | 
			
		||||
-		u32 opt;
 | 
			
		||||
-		u16 reg;
 | 
			
		||||
-		u8  mask;
 | 
			
		||||
-	} cfg[] = {
 | 
			
		||||
-		{ WAKE_PHY,   Config3, LinkUp },
 | 
			
		||||
-		{ WAKE_UCAST, Config5, UWF },
 | 
			
		||||
-		{ WAKE_BCAST, Config5, BWF },
 | 
			
		||||
-		{ WAKE_MCAST, Config5, MWF },
 | 
			
		||||
-		{ WAKE_ANY,   Config5, LanWake },
 | 
			
		||||
-		{ WAKE_MAGIC, Config3, MagicPacket }
 | 
			
		||||
-	};
 | 
			
		||||
-	unsigned int i, tmp = ARRAY_SIZE(cfg);
 | 
			
		||||
-	u8 options;
 | 
			
		||||
-
 | 
			
		||||
 	rtl_unlock_config_regs(tp);
 | 
			
		||||
 
 | 
			
		||||
 	if (rtl_is_8168evl_up(tp)) {
 | 
			
		||||
-		tmp--;
 | 
			
		||||
 		if (wolopts & WAKE_MAGIC)
 | 
			
		||||
 			rtl_eri_set_bits(tp, 0x0dc, MagicPacket_v2);
 | 
			
		||||
 		else
 | 
			
		||||
 			rtl_eri_clear_bits(tp, 0x0dc, MagicPacket_v2);
 | 
			
		||||
 	} else if (rtl_is_8125(tp)) {
 | 
			
		||||
-		tmp--;
 | 
			
		||||
 		if (wolopts & WAKE_MAGIC)
 | 
			
		||||
 			r8168_mac_ocp_modify(tp, 0xc0b6, 0, BIT(0));
 | 
			
		||||
 		else
 | 
			
		||||
 			r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config3, MagicPacket,
 | 
			
		||||
+				    wolopts & WAKE_MAGIC);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	for (i = 0; i < tmp; i++) {
 | 
			
		||||
-		options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask;
 | 
			
		||||
-		if (wolopts & cfg[i].opt)
 | 
			
		||||
-			options |= cfg[i].mask;
 | 
			
		||||
-		RTL_W8(tp, cfg[i].reg, options);
 | 
			
		||||
-	}
 | 
			
		||||
+	r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY);
 | 
			
		||||
+	r8169_mod_reg8_cond(tp, Config5, UWF, wolopts & WAKE_UCAST);
 | 
			
		||||
+	r8169_mod_reg8_cond(tp, Config5, BWF, wolopts & WAKE_BCAST);
 | 
			
		||||
+	r8169_mod_reg8_cond(tp, Config5, MWF, wolopts & WAKE_MCAST);
 | 
			
		||||
+	r8169_mod_reg8_cond(tp, Config5, LanWake, wolopts);
 | 
			
		||||
 
 | 
			
		||||
 	switch (tp->mac_version) {
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
 | 
			
		||||
-		options = RTL_R8(tp, Config1) & ~PMEnable;
 | 
			
		||||
-		if (wolopts)
 | 
			
		||||
-			options |= PMEnable;
 | 
			
		||||
-		RTL_W8(tp, Config1, options);
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config1, PMEnable, wolopts);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_34:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_37:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
-		if (wolopts)
 | 
			
		||||
-			rtl_mod_config2(tp, 0, PME_SIGNAL);
 | 
			
		||||
-		else
 | 
			
		||||
-			rtl_mod_config2(tp, PME_SIGNAL, 0);
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
 		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
From 330dc2297c82953dff402e0b4176a5383a618538 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 6 Nov 2024 17:56:28 +0100
 | 
			
		||||
Subject: [PATCH] r8169: improve rtl_set_d3_pll_down
 | 
			
		||||
 | 
			
		||||
Make use of new helper r8169_mod_reg8_cond() and move from a switch()
 | 
			
		||||
to an if() clause. Benefit is that we don't have to touch this piece of
 | 
			
		||||
code each time support for a new chip version is added.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/e1ccdb85-a4ed-4800-89c2-89770ff06452@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 18 +++++-------------
 | 
			
		||||
 1 file changed, 5 insertions(+), 13 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -1431,19 +1431,11 @@ static enum rtl_dash_type rtl_get_dash_t
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_set_d3_pll_down(struct rtl8169_private *tp, bool enable)
 | 
			
		||||
 {
 | 
			
		||||
-	switch (tp->mac_version) {
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
-		if (enable)
 | 
			
		||||
-			RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
 | 
			
		||||
-		else
 | 
			
		||||
-			RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | D3_NO_PLL_DOWN);
 | 
			
		||||
-		break;
 | 
			
		||||
-	default:
 | 
			
		||||
-		break;
 | 
			
		||||
-	}
 | 
			
		||||
+	if (tp->mac_version >= RTL_GIGA_MAC_VER_25 &&
 | 
			
		||||
+	    tp->mac_version != RTL_GIGA_MAC_VER_28 &&
 | 
			
		||||
+	    tp->mac_version != RTL_GIGA_MAC_VER_31 &&
 | 
			
		||||
+	    tp->mac_version != RTL_GIGA_MAC_VER_38)
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, PMCH, D3_NO_PLL_DOWN, !enable);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl_reset_packet_filter(struct rtl8169_private *tp)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
From e3e9e9039fa6ae885c7d5c954d7b9f105fa23e8f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Wed, 6 Nov 2024 17:57:08 +0100
 | 
			
		||||
Subject: [PATCH] r8169: align WAKE_PHY handling with r8125/r8126 vendor
 | 
			
		||||
 drivers
 | 
			
		||||
 | 
			
		||||
Vendor drivers r8125/r8126 apply this additional magic setting when
 | 
			
		||||
enabling WAKE_PHY, so do the same here.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/51130715-45be-4db5-abb7-05d87e1f5df9@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -1562,6 +1562,9 @@ static void __rtl8169_set_wol(struct rtl
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	r8169_mod_reg8_cond(tp, Config3, LinkUp, wolopts & WAKE_PHY);
 | 
			
		||||
+	if (rtl_is_8125(tp))
 | 
			
		||||
+		r8168_mac_ocp_modify(tp, 0xe0c6, 0x3f,
 | 
			
		||||
+				     wolopts & WAKE_PHY ? 0x13 : 0);
 | 
			
		||||
 	r8169_mod_reg8_cond(tp, Config5, UWF, wolopts & WAKE_UCAST);
 | 
			
		||||
 	r8169_mod_reg8_cond(tp, Config5, BWF, wolopts & WAKE_BCAST);
 | 
			
		||||
 	r8169_mod_reg8_cond(tp, Config5, MWF, wolopts & WAKE_MCAST);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
From 7a3bcd39ae1f0e3ab896d9df62339ab4297a0bfd Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Sat, 9 Nov 2024 23:12:12 +0100
 | 
			
		||||
Subject: [PATCH] r8169: use helper r8169_mod_reg8_cond to simplify
 | 
			
		||||
 rtl_jumbo_config
 | 
			
		||||
 | 
			
		||||
Use recently added helper r8169_mod_reg8_cond() to simplify jumbo
 | 
			
		||||
mode configuration.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/3df1d484-a02e-46e7-8f75-db5b428e422e@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 77 ++++-------------------
 | 
			
		||||
 1 file changed, 11 insertions(+), 66 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -2545,86 +2545,31 @@ static void rtl8169_init_ring_indexes(st
 | 
			
		||||
 	tp->dirty_tx = tp->cur_tx = tp->cur_rx = 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
 | 
			
		||||
-	RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
 | 
			
		||||
-	RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, MaxTxPacketSize, 0x24);
 | 
			
		||||
-	RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
 | 
			
		||||
-	RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, MaxTxPacketSize, 0x3f);
 | 
			
		||||
-	RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
 | 
			
		||||
-	RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0));
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
 | 
			
		||||
-{
 | 
			
		||||
-	RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 static void rtl_jumbo_config(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	bool jumbo = tp->dev->mtu > ETH_DATA_LEN;
 | 
			
		||||
 	int readrq = 4096;
 | 
			
		||||
 
 | 
			
		||||
+	if (jumbo && tp->mac_version >= RTL_GIGA_MAC_VER_17 &&
 | 
			
		||||
+	    tp->mac_version <= RTL_GIGA_MAC_VER_26)
 | 
			
		||||
+		readrq = 512;
 | 
			
		||||
+
 | 
			
		||||
 	rtl_unlock_config_regs(tp);
 | 
			
		||||
 	switch (tp->mac_version) {
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_17:
 | 
			
		||||
-		if (jumbo) {
 | 
			
		||||
-			readrq = 512;
 | 
			
		||||
-			r8168b_1_hw_jumbo_enable(tp);
 | 
			
		||||
-		} else {
 | 
			
		||||
-			r8168b_1_hw_jumbo_disable(tp);
 | 
			
		||||
-		}
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config4, BIT(0), jumbo);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26:
 | 
			
		||||
-		if (jumbo) {
 | 
			
		||||
-			readrq = 512;
 | 
			
		||||
-			r8168c_hw_jumbo_enable(tp);
 | 
			
		||||
-		} else {
 | 
			
		||||
-			r8168c_hw_jumbo_disable(tp);
 | 
			
		||||
-		}
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo);
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config4, Jumbo_En1, jumbo);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_28:
 | 
			
		||||
-		if (jumbo)
 | 
			
		||||
-			r8168dp_hw_jumbo_enable(tp);
 | 
			
		||||
-		else
 | 
			
		||||
-			r8168dp_hw_jumbo_disable(tp);
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
 | 
			
		||||
-		if (jumbo)
 | 
			
		||||
-			r8168e_hw_jumbo_enable(tp);
 | 
			
		||||
-		else
 | 
			
		||||
-			r8168e_hw_jumbo_disable(tp);
 | 
			
		||||
+		RTL_W8(tp, MaxTxPacketSize, jumbo ? 0x24 : 0x3f);
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config3, Jumbo_En0, jumbo);
 | 
			
		||||
+		r8169_mod_reg8_cond(tp, Config4, BIT(0), jumbo);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
 		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
From e340bff27e63ed61a1e9895bed546107859e48a7 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Fri, 8 Nov 2024 08:08:24 +0100
 | 
			
		||||
Subject: [PATCH] r8169: copy vendor driver 2.5G/5G EEE advertisement
 | 
			
		||||
 constraints
 | 
			
		||||
 | 
			
		||||
Vendor driver r8125 doesn't advertise 2.5G EEE on RTL8125A, and r8126
 | 
			
		||||
doesn't advertise 5G EEE. Likely there are compatibility issues,
 | 
			
		||||
therefore do the same in r8169.
 | 
			
		||||
With this change we don't have to disable 2.5G EEE advertisement in
 | 
			
		||||
rtl8125a_config_eee_phy() any longer.
 | 
			
		||||
We use new phylib accessor phy_set_eee_broken() to mark the respective
 | 
			
		||||
EEE modes as broken.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/ce185e10-8a2f-4cf8-a49b-fd8fb3c3c8a1@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c       |  6 ++++++
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_phy_config.c | 16 ++++------------
 | 
			
		||||
 2 files changed, 10 insertions(+), 12 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -5234,6 +5234,11 @@ static int r8169_mdio_register(struct rt
 | 
			
		||||
 		phy_support_eee(tp->phydev);
 | 
			
		||||
 	phy_support_asym_pause(tp->phydev);
 | 
			
		||||
 
 | 
			
		||||
+	/* mimic behavior of r8125/r8126 vendor drivers */
 | 
			
		||||
+	if (tp->mac_version == RTL_GIGA_MAC_VER_61)
 | 
			
		||||
+		tp->phydev->eee_broken_modes |= MDIO_EEE_2_5GT;
 | 
			
		||||
+	tp->phydev->eee_broken_modes |= MDIO_EEE_5GT;
 | 
			
		||||
+
 | 
			
		||||
 	/* PHY will be woken up in rtl_open() */
 | 
			
		||||
 	phy_suspend(tp->phydev);
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -96,15 +96,7 @@ static void rtl8125_common_config_eee_ph
 | 
			
		||||
 	phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void rtl8125a_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
-{
 | 
			
		||||
-	rtl8168g_config_eee_phy(phydev);
 | 
			
		||||
-	/* disable EEE at 2.5Gbps */
 | 
			
		||||
-	phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000);
 | 
			
		||||
-	rtl8125_common_config_eee_phy(phydev);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void rtl8125b_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
+static void rtl8125_config_eee_phy(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	rtl8168g_config_eee_phy(phydev);
 | 
			
		||||
 	rtl8125_common_config_eee_phy(phydev);
 | 
			
		||||
@@ -1066,7 +1058,7 @@ static void rtl8125a_2_hw_phy_config(str
 | 
			
		||||
 	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
 
 | 
			
		||||
 	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
-	rtl8125a_config_eee_phy(phydev);
 | 
			
		||||
+	rtl8125_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8125b_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
@@ -1106,7 +1098,7 @@ static void rtl8125b_hw_phy_config(struc
 | 
			
		||||
 
 | 
			
		||||
 	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
 	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
-	rtl8125b_config_eee_phy(phydev);
 | 
			
		||||
+	rtl8125_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8125d_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
@@ -1116,7 +1108,7 @@ static void rtl8125d_hw_phy_config(struc
 | 
			
		||||
 	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
 	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
 	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
-	rtl8125b_config_eee_phy(phydev);
 | 
			
		||||
+	rtl8125_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
From 2e20bf8cc05766dcd0357cdfcada49e1bc45512b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Mon, 2 Dec 2024 21:14:35 +0100
 | 
			
		||||
Subject: [PATCH] r8169: remove unused flag RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE
 | 
			
		||||
 | 
			
		||||
After 854d71c555dfc3 ("r8169: remove original workaround for RTL8125
 | 
			
		||||
broken rx issue") this flag isn't used any longer. So remove it.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
 | 
			
		||||
Link: https://patch.msgid.link/d9dd214b-3027-4f60-b0e8-6f34a0c76582@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c | 3 ---
 | 
			
		||||
 1 file changed, 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -623,7 +623,6 @@ struct rtl8169_tc_offsets {
 | 
			
		||||
 enum rtl_flag {
 | 
			
		||||
 	RTL_FLAG_TASK_ENABLED = 0,
 | 
			
		||||
 	RTL_FLAG_TASK_RESET_PENDING,
 | 
			
		||||
-	RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE,
 | 
			
		||||
 	RTL_FLAG_TASK_TX_TIMEOUT,
 | 
			
		||||
 	RTL_FLAG_MAX
 | 
			
		||||
 };
 | 
			
		||||
@@ -4728,8 +4727,6 @@ static void rtl_task(struct work_struct
 | 
			
		||||
 reset:
 | 
			
		||||
 		rtl_reset_work(tp);
 | 
			
		||||
 		netif_wake_queue(tp->dev);
 | 
			
		||||
-	} else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) {
 | 
			
		||||
-		rtl_reset_work(tp);
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
From bb18265c3aba92b91a1355609769f3e967b65dee Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Mon, 2 Dec 2024 21:20:02 +0100
 | 
			
		||||
Subject: [PATCH] r8169: remove support for chip version 11
 | 
			
		||||
 | 
			
		||||
This is a follow-up to 982300c115d2 ("r8169: remove detection of chip
 | 
			
		||||
version 11 (early RTL8168b)"). Nobody complained yet, so remove
 | 
			
		||||
support for this chip version.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/b689ab6d-20b5-4b64-bd7e-531a0a972ba3@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169.h            |  2 +-
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c       | 14 +-------------
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_phy_config.c | 10 ----------
 | 
			
		||||
 3 files changed, 2 insertions(+), 24 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
@@ -23,7 +23,7 @@ enum mac_version {
 | 
			
		||||
 	RTL_GIGA_MAC_VER_08,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_09,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_10,
 | 
			
		||||
-	RTL_GIGA_MAC_VER_11,
 | 
			
		||||
+	/* support for RTL_GIGA_MAC_VER_11 has been removed */
 | 
			
		||||
 	/* RTL_GIGA_MAC_VER_12 was handled the same as VER_17 */
 | 
			
		||||
 	/* RTL_GIGA_MAC_VER_13 was merged with VER_10 */
 | 
			
		||||
 	RTL_GIGA_MAC_VER_14,
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -103,7 +103,6 @@ static const struct {
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_08] = {"RTL8102e"				},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_09] = {"RTL8102e/RTL8103e"			},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_10] = {"RTL8101e/RTL8100e"			},
 | 
			
		||||
-	[RTL_GIGA_MAC_VER_11] = {"RTL8168b/8111b"			},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_14] = {"RTL8401"				},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_17] = {"RTL8168b/8111b"			},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_18] = {"RTL8168cp/8111cp"			},
 | 
			
		||||
@@ -2335,7 +2334,7 @@ static enum mac_version rtl8169_get_mac_
 | 
			
		||||
 
 | 
			
		||||
 		/* 8168B family. */
 | 
			
		||||
 		{ 0x7c8, 0x380,	RTL_GIGA_MAC_VER_17 },
 | 
			
		||||
-		/* This one is very old and rare, let's see if anybody complains.
 | 
			
		||||
+		/* This one is very old and rare, support has been removed.
 | 
			
		||||
 		 * { 0x7c8, 0x300,	RTL_GIGA_MAC_VER_11 },
 | 
			
		||||
 		 */
 | 
			
		||||
 
 | 
			
		||||
@@ -3805,7 +3804,6 @@ static void rtl_hw_config(struct rtl8169
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_08] = rtl_hw_start_8102e_3,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_09] = rtl_hw_start_8102e_2,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_10] = NULL,
 | 
			
		||||
-		[RTL_GIGA_MAC_VER_11] = rtl_hw_start_8168b,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_14] = rtl_hw_start_8401,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_17] = rtl_hw_start_8168b,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_18] = rtl_hw_start_8168cp_1,
 | 
			
		||||
@@ -4681,12 +4679,6 @@ static irqreturn_t rtl8169_interrupt(int
 | 
			
		||||
 	if (status & LinkChg)
 | 
			
		||||
 		phy_mac_interrupt(tp->phydev);
 | 
			
		||||
 
 | 
			
		||||
-	if (unlikely(status & RxFIFOOver &&
 | 
			
		||||
-	    tp->mac_version == RTL_GIGA_MAC_VER_11)) {
 | 
			
		||||
-		netif_stop_queue(tp->dev);
 | 
			
		||||
-		rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
 	rtl_irq_disable(tp);
 | 
			
		||||
 	napi_schedule(&tp->napi);
 | 
			
		||||
 out:
 | 
			
		||||
@@ -5106,9 +5098,6 @@ static void rtl_set_irq_mask(struct rtl8
 | 
			
		||||
 
 | 
			
		||||
 	if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
 | 
			
		||||
 		tp->irq_mask |= SYSErr | RxFIFOOver;
 | 
			
		||||
-	else if (tp->mac_version == RTL_GIGA_MAC_VER_11)
 | 
			
		||||
-		/* special workaround needed */
 | 
			
		||||
-		tp->irq_mask |= RxFIFOOver;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int rtl_alloc_irq(struct rtl8169_private *tp)
 | 
			
		||||
@@ -5302,7 +5291,6 @@ static int rtl_jumbo_max(struct rtl8169_
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
 | 
			
		||||
 		return JUMBO_7K;
 | 
			
		||||
 	/* RTL8168b */
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_11:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_17:
 | 
			
		||||
 		return JUMBO_4K;
 | 
			
		||||
 	/* RTL8168c */
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -276,15 +276,6 @@ static void rtl8169sce_hw_phy_config(str
 | 
			
		||||
 	rtl_writephy_batch(phydev, phy_reg_init);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void rtl8168bb_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
-				    struct phy_device *phydev)
 | 
			
		||||
-{
 | 
			
		||||
-	phy_write(phydev, 0x1f, 0x0001);
 | 
			
		||||
-	phy_set_bits(phydev, 0x16, BIT(0));
 | 
			
		||||
-	phy_write(phydev, 0x10, 0xf41b);
 | 
			
		||||
-	phy_write(phydev, 0x1f, 0x0000);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 static void rtl8168bef_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
 				     struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1136,7 +1127,6 @@ void r8169_hw_phy_config(struct rtl8169_
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_08] = rtl8102e_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_09] = rtl8102e_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_10] = NULL,
 | 
			
		||||
-		[RTL_GIGA_MAC_VER_11] = rtl8168bb_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_14] = rtl8401_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_17] = rtl8168bef_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_18] = rtl8168cp_1_hw_phy_config,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,257 @@
 | 
			
		|||
From b299ea0069284186b0d3d54aebe87f0d195d457a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Fri, 13 Dec 2024 20:01:41 +0100
 | 
			
		||||
Subject: [PATCH] r8169: adjust version numbering for RTL8126
 | 
			
		||||
 | 
			
		||||
Adjust version numbering for RTL8126, so that it doesn't overlap with
 | 
			
		||||
new RTL8125 versions.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/6a354364-20e9-48ad-a198-468264288757@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169.h          |  4 +-
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c     | 62 +++++++++----------
 | 
			
		||||
 .../net/ethernet/realtek/r8169_phy_config.c   |  4 +-
 | 
			
		||||
 3 files changed, 35 insertions(+), 35 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
@@ -69,8 +69,8 @@ enum mac_version {
 | 
			
		||||
 	RTL_GIGA_MAC_VER_61,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_63,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_64,
 | 
			
		||||
-	RTL_GIGA_MAC_VER_65,
 | 
			
		||||
-	RTL_GIGA_MAC_VER_66,
 | 
			
		||||
+	RTL_GIGA_MAC_VER_70,
 | 
			
		||||
+	RTL_GIGA_MAC_VER_71,
 | 
			
		||||
 	RTL_GIGA_MAC_NONE
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -139,8 +139,8 @@ static const struct {
 | 
			
		||||
 	/* reserve 62 for CFG_METHOD_4 in the vendor driver */
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_63] = {"RTL8125B",		FIRMWARE_8125B_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_64] = {"RTL8125D",		FIRMWARE_8125D_1},
 | 
			
		||||
-	[RTL_GIGA_MAC_VER_65] = {"RTL8126A",		FIRMWARE_8126A_2},
 | 
			
		||||
-	[RTL_GIGA_MAC_VER_66] = {"RTL8126A",		FIRMWARE_8126A_3},
 | 
			
		||||
+	[RTL_GIGA_MAC_VER_70] = {"RTL8126A",		FIRMWARE_8126A_2},
 | 
			
		||||
+	[RTL_GIGA_MAC_VER_71] = {"RTL8126A",		FIRMWARE_8126A_3},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct pci_device_id rtl8169_pci_tbl[] = {
 | 
			
		||||
@@ -1228,7 +1228,7 @@ static void rtl_writephy(struct rtl8169_
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_31:
 | 
			
		||||
 		r8168dp_2_mdio_write(tp, location, val);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		r8168g_mdio_write(tp, location, val);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
@@ -1243,7 +1243,7 @@ static int rtl_readphy(struct rtl8169_pr
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_28:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_31:
 | 
			
		||||
 		return r8168dp_2_mdio_read(tp, location);
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		return r8168g_mdio_read(tp, location);
 | 
			
		||||
 	default:
 | 
			
		||||
 		return r8169_mdio_read(tp, location);
 | 
			
		||||
@@ -1574,7 +1574,7 @@ static void __rtl8169_set_wol(struct rtl
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_34:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_37:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		r8169_mod_reg8_cond(tp, Config2, PME_SIGNAL, wolopts);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
@@ -2047,7 +2047,7 @@ static void rtl_set_eee_txidle_timer(str
 | 
			
		||||
 		tp->tx_lpi_timer = timer_val;
 | 
			
		||||
 		r8168_mac_ocp_write(tp, 0xe048, timer_val);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		tp->tx_lpi_timer = timer_val;
 | 
			
		||||
 		RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -2255,8 +2255,8 @@ static enum mac_version rtl8169_get_mac_
 | 
			
		||||
 		enum mac_version ver;
 | 
			
		||||
 	} mac_info[] = {
 | 
			
		||||
 		/* 8126A family. */
 | 
			
		||||
-		{ 0x7cf, 0x64a,	RTL_GIGA_MAC_VER_66 },
 | 
			
		||||
-		{ 0x7cf, 0x649,	RTL_GIGA_MAC_VER_65 },
 | 
			
		||||
+		{ 0x7cf, 0x64a,	RTL_GIGA_MAC_VER_71 },
 | 
			
		||||
+		{ 0x7cf, 0x649,	RTL_GIGA_MAC_VER_70 },
 | 
			
		||||
 
 | 
			
		||||
 		/* 8125D family. */
 | 
			
		||||
 		{ 0x7cf, 0x688,	RTL_GIGA_MAC_VER_64 },
 | 
			
		||||
@@ -2528,7 +2528,7 @@ static void rtl_init_rxcfg(struct rtl816
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_61:
 | 
			
		||||
 		RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
 | 
			
		||||
 			RX_PAUSE_SLOT_ON);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -2660,7 +2660,7 @@ static void rtl_wait_txrx_fifo_empty(str
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
 | 
			
		||||
 		rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
 | 
			
		||||
 		rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
 | 
			
		||||
 		rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
 | 
			
		||||
@@ -2903,7 +2903,7 @@ static void rtl_enable_exit_l1(struct rt
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
 | 
			
		||||
 		rtl_eri_set_bits(tp, 0xd4, 0x0c00);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
@@ -2917,7 +2917,7 @@ static void rtl_disable_exit_l1(struct r
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
 | 
			
		||||
 		rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
@@ -2943,8 +2943,8 @@ static void rtl_hw_aspm_clkreq_enable(st
 | 
			
		||||
 
 | 
			
		||||
 		rtl_mod_config5(tp, 0, ASPM_en);
 | 
			
		||||
 		switch (tp->mac_version) {
 | 
			
		||||
-		case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
-		case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+		case RTL_GIGA_MAC_VER_70:
 | 
			
		||||
+		case RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 			val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
 | 
			
		||||
 			RTL_W8(tp, INT_CFG0_8125, val8);
 | 
			
		||||
 			break;
 | 
			
		||||
@@ -2955,7 +2955,7 @@ static void rtl_hw_aspm_clkreq_enable(st
 | 
			
		||||
 
 | 
			
		||||
 		switch (tp->mac_version) {
 | 
			
		||||
 		case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
 | 
			
		||||
-		case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+		case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 			/* reset ephy tx/rx disable timer */
 | 
			
		||||
 			r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
 | 
			
		||||
 			/* chip can trigger L1.2 */
 | 
			
		||||
@@ -2967,7 +2967,7 @@ static void rtl_hw_aspm_clkreq_enable(st
 | 
			
		||||
 	} else {
 | 
			
		||||
 		switch (tp->mac_version) {
 | 
			
		||||
 		case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
 | 
			
		||||
-		case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+		case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 			r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
 | 
			
		||||
 			break;
 | 
			
		||||
 		default:
 | 
			
		||||
@@ -2975,8 +2975,8 @@ static void rtl_hw_aspm_clkreq_enable(st
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
 		switch (tp->mac_version) {
 | 
			
		||||
-		case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
-		case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+		case RTL_GIGA_MAC_VER_70:
 | 
			
		||||
+		case RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 			val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
 | 
			
		||||
 			RTL_W8(tp, INT_CFG0_8125, val8);
 | 
			
		||||
 			break;
 | 
			
		||||
@@ -3696,12 +3696,12 @@ static void rtl_hw_start_8125_common(str
 | 
			
		||||
 	/* disable new tx descriptor format */
 | 
			
		||||
 	r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
 | 
			
		||||
 
 | 
			
		||||
-	if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
 | 
			
		||||
-	    tp->mac_version == RTL_GIGA_MAC_VER_66)
 | 
			
		||||
+	if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
 | 
			
		||||
+	    tp->mac_version == RTL_GIGA_MAC_VER_71)
 | 
			
		||||
 		RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
 | 
			
		||||
 
 | 
			
		||||
-	if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
 | 
			
		||||
-	    tp->mac_version == RTL_GIGA_MAC_VER_66)
 | 
			
		||||
+	if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
 | 
			
		||||
+	    tp->mac_version == RTL_GIGA_MAC_VER_71)
 | 
			
		||||
 		r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
 | 
			
		||||
 	else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
 | 
			
		||||
 		r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
 | 
			
		||||
@@ -3719,8 +3719,8 @@ static void rtl_hw_start_8125_common(str
 | 
			
		||||
 	r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
 | 
			
		||||
 	r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
 | 
			
		||||
 	r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
 | 
			
		||||
-	if (tp->mac_version == RTL_GIGA_MAC_VER_65 ||
 | 
			
		||||
-	    tp->mac_version == RTL_GIGA_MAC_VER_66)
 | 
			
		||||
+	if (tp->mac_version == RTL_GIGA_MAC_VER_70 ||
 | 
			
		||||
+	    tp->mac_version == RTL_GIGA_MAC_VER_71)
 | 
			
		||||
 		r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
 | 
			
		||||
 	else
 | 
			
		||||
 		r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
 | 
			
		||||
@@ -3839,8 +3839,8 @@ static void rtl_hw_config(struct rtl8169
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
 | 
			
		||||
-		[RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
 | 
			
		||||
-		[RTL_GIGA_MAC_VER_66] = rtl_hw_start_8126a,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
 | 
			
		||||
 	};
 | 
			
		||||
 
 | 
			
		||||
 	if (hw_configs[tp->mac_version])
 | 
			
		||||
@@ -3861,8 +3861,8 @@ static void rtl_hw_start_8125(struct rtl
 | 
			
		||||
 			RTL_W32(tp, i, 0);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_63:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_70:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		for (i = 0xa00; i < 0xa80; i += 4)
 | 
			
		||||
 			RTL_W32(tp, i, 0);
 | 
			
		||||
 		RTL_W16(tp, INT_CFG1_8125, 0x0000);
 | 
			
		||||
@@ -4094,7 +4094,7 @@ static void rtl8169_cleanup(struct rtl81
 | 
			
		||||
 		RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
 | 
			
		||||
 		rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		rtl_enable_rxdvgate(tp);
 | 
			
		||||
 		fsleep(2000);
 | 
			
		||||
 		break;
 | 
			
		||||
@@ -4251,7 +4251,7 @@ static unsigned int rtl_quirk_packet_pad
 | 
			
		||||
 
 | 
			
		||||
 	switch (tp->mac_version) {
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_34:
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		padto = max_t(unsigned int, padto, ETH_ZLEN);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
@@ -5272,7 +5272,7 @@ static void rtl_hw_initialize(struct rtl
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
 | 
			
		||||
 		rtl_hw_init_8168g(tp);
 | 
			
		||||
 		break;
 | 
			
		||||
-	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_71:
 | 
			
		||||
 		rtl_hw_init_8125(tp);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -1162,8 +1162,8 @@ void r8169_hw_phy_config(struct rtl8169_
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
 | 
			
		||||
-		[RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
 | 
			
		||||
-		[RTL_GIGA_MAC_VER_66] = rtl8126a_hw_phy_config,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
 | 
			
		||||
 	};
 | 
			
		||||
 
 | 
			
		||||
 	if (phy_configs[ver])
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
From b3593df26ab19f114d613693fa8a92ab202803d0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: ChunHao Lin <hau@realtek.com>
 | 
			
		||||
Date: Fri, 13 Dec 2024 20:02:58 +0100
 | 
			
		||||
Subject: [PATCH] r8169: add support for RTL8125D rev.b
 | 
			
		||||
 | 
			
		||||
Add support for RTL8125D rev.b. Its XID is 0x689. It is basically
 | 
			
		||||
based on the one with XID 0x688, but with different firmware file.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: ChunHao Lin <hau@realtek.com>
 | 
			
		||||
[hkallweit1@gmail.com: rebased after adjusted version numbering]
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Simon Horman <horms@kernel.org>
 | 
			
		||||
Link: https://patch.msgid.link/75e5e9ec-d01f-43ac-b0f4-e7456baf18d1@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169.h            | 1 +
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c       | 6 ++++++
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_phy_config.c | 1 +
 | 
			
		||||
 3 files changed, 8 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
@@ -69,6 +69,7 @@ enum mac_version {
 | 
			
		||||
 	RTL_GIGA_MAC_VER_61,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_63,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_64,
 | 
			
		||||
+	RTL_GIGA_MAC_VER_65,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_70,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_71,
 | 
			
		||||
 	RTL_GIGA_MAC_NONE
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -56,6 +56,7 @@
 | 
			
		||||
 #define FIRMWARE_8125A_3	"rtl_nic/rtl8125a-3.fw"
 | 
			
		||||
 #define FIRMWARE_8125B_2	"rtl_nic/rtl8125b-2.fw"
 | 
			
		||||
 #define FIRMWARE_8125D_1	"rtl_nic/rtl8125d-1.fw"
 | 
			
		||||
+#define FIRMWARE_8125D_2	"rtl_nic/rtl8125d-2.fw"
 | 
			
		||||
 #define FIRMWARE_8126A_2	"rtl_nic/rtl8126a-2.fw"
 | 
			
		||||
 #define FIRMWARE_8126A_3	"rtl_nic/rtl8126a-3.fw"
 | 
			
		||||
 
 | 
			
		||||
@@ -139,6 +140,7 @@ static const struct {
 | 
			
		||||
 	/* reserve 62 for CFG_METHOD_4 in the vendor driver */
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_63] = {"RTL8125B",		FIRMWARE_8125B_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_64] = {"RTL8125D",		FIRMWARE_8125D_1},
 | 
			
		||||
+	[RTL_GIGA_MAC_VER_65] = {"RTL8125D",		FIRMWARE_8125D_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_70] = {"RTL8126A",		FIRMWARE_8126A_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_71] = {"RTL8126A",		FIRMWARE_8126A_3},
 | 
			
		||||
 };
 | 
			
		||||
@@ -706,6 +708,7 @@ MODULE_FIRMWARE(FIRMWARE_8107E_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125A_3);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125B_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125D_1);
 | 
			
		||||
+MODULE_FIRMWARE(FIRMWARE_8125D_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8126A_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8126A_3);
 | 
			
		||||
 
 | 
			
		||||
@@ -2259,6 +2262,7 @@ static enum mac_version rtl8169_get_mac_
 | 
			
		||||
 		{ 0x7cf, 0x649,	RTL_GIGA_MAC_VER_70 },
 | 
			
		||||
 
 | 
			
		||||
 		/* 8125D family. */
 | 
			
		||||
+		{ 0x7cf, 0x689,	RTL_GIGA_MAC_VER_65 },
 | 
			
		||||
 		{ 0x7cf, 0x688,	RTL_GIGA_MAC_VER_64 },
 | 
			
		||||
 
 | 
			
		||||
 		/* 8125B family. */
 | 
			
		||||
@@ -3839,6 +3843,7 @@ static void rtl_hw_config(struct rtl8169
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
 | 
			
		||||
 	};
 | 
			
		||||
@@ -3857,6 +3862,7 @@ static void rtl_hw_start_8125(struct rtl
 | 
			
		||||
 	switch (tp->mac_version) {
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_61:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_64:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
 		for (i = 0xa00; i < 0xb00; i += 4)
 | 
			
		||||
 			RTL_W32(tp, i, 0);
 | 
			
		||||
 		break;
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -1162,6 +1162,7 @@ void r8169_hw_phy_config(struct rtl8169_
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
 | 
			
		||||
 	};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,184 @@
 | 
			
		|||
From b11bff90f2ad52c5c55c822ecd20326619a73898 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: ChunHao Lin <hau@realtek.com>
 | 
			
		||||
Date: Tue, 7 Jan 2025 14:43:55 +0800
 | 
			
		||||
Subject: [PATCH] r8169: add support for RTL8125BP rev.b
 | 
			
		||||
 | 
			
		||||
Add support for RTL8125BP rev.b. Its XID is 0x689. This chip supports
 | 
			
		||||
DASH and its dash type is "RTL_DASH_25_BP".
 | 
			
		||||
 | 
			
		||||
Signed-off-by: ChunHao Lin <hau@realtek.com>
 | 
			
		||||
Reviewed-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/20250107064355.104711-1-hau@realtek.com
 | 
			
		||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169.h          |  1 +
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169_main.c     | 30 +++++++++++++++++++
 | 
			
		||||
 .../net/ethernet/realtek/r8169_phy_config.c   | 23 ++++++++++++++
 | 
			
		||||
 3 files changed, 54 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169.h
 | 
			
		||||
@@ -70,6 +70,7 @@ enum mac_version {
 | 
			
		||||
 	RTL_GIGA_MAC_VER_63,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_64,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_65,
 | 
			
		||||
+	RTL_GIGA_MAC_VER_66,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_70,
 | 
			
		||||
 	RTL_GIGA_MAC_VER_71,
 | 
			
		||||
 	RTL_GIGA_MAC_NONE
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_main.c
 | 
			
		||||
@@ -57,6 +57,7 @@
 | 
			
		||||
 #define FIRMWARE_8125B_2	"rtl_nic/rtl8125b-2.fw"
 | 
			
		||||
 #define FIRMWARE_8125D_1	"rtl_nic/rtl8125d-1.fw"
 | 
			
		||||
 #define FIRMWARE_8125D_2	"rtl_nic/rtl8125d-2.fw"
 | 
			
		||||
+#define FIRMWARE_8125BP_2	"rtl_nic/rtl8125bp-2.fw"
 | 
			
		||||
 #define FIRMWARE_8126A_2	"rtl_nic/rtl8126a-2.fw"
 | 
			
		||||
 #define FIRMWARE_8126A_3	"rtl_nic/rtl8126a-3.fw"
 | 
			
		||||
 
 | 
			
		||||
@@ -141,6 +142,7 @@ static const struct {
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_63] = {"RTL8125B",		FIRMWARE_8125B_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_64] = {"RTL8125D",		FIRMWARE_8125D_1},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_65] = {"RTL8125D",		FIRMWARE_8125D_2},
 | 
			
		||||
+	[RTL_GIGA_MAC_VER_66] = {"RTL8125BP",		FIRMWARE_8125BP_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_70] = {"RTL8126A",		FIRMWARE_8126A_2},
 | 
			
		||||
 	[RTL_GIGA_MAC_VER_71] = {"RTL8126A",		FIRMWARE_8126A_3},
 | 
			
		||||
 };
 | 
			
		||||
@@ -632,6 +634,7 @@ enum rtl_dash_type {
 | 
			
		||||
 	RTL_DASH_NONE,
 | 
			
		||||
 	RTL_DASH_DP,
 | 
			
		||||
 	RTL_DASH_EP,
 | 
			
		||||
+	RTL_DASH_25_BP,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 struct rtl8169_private {
 | 
			
		||||
@@ -709,6 +712,7 @@ MODULE_FIRMWARE(FIRMWARE_8125A_3);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125B_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125D_1);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8125D_2);
 | 
			
		||||
+MODULE_FIRMWARE(FIRMWARE_8125BP_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8126A_2);
 | 
			
		||||
 MODULE_FIRMWARE(FIRMWARE_8126A_3);
 | 
			
		||||
 
 | 
			
		||||
@@ -1361,10 +1365,19 @@ static void rtl8168ep_driver_start(struc
 | 
			
		||||
 		rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8125bp_driver_start(struct rtl8169_private *tp)
 | 
			
		||||
+{
 | 
			
		||||
+	r8168ep_ocp_write(tp, 0x01, 0x14, OOB_CMD_DRIVER_START);
 | 
			
		||||
+	r8168ep_ocp_write(tp, 0x01, 0x18, 0x00);
 | 
			
		||||
+	r8168ep_ocp_write(tp, 0x01, 0x10, 0x01);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void rtl8168_driver_start(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	if (tp->dash_type == RTL_DASH_DP)
 | 
			
		||||
 		rtl8168dp_driver_start(tp);
 | 
			
		||||
+	else if (tp->dash_type == RTL_DASH_25_BP)
 | 
			
		||||
+		rtl8125bp_driver_start(tp);
 | 
			
		||||
 	else
 | 
			
		||||
 		rtl8168ep_driver_start(tp);
 | 
			
		||||
 }
 | 
			
		||||
@@ -1385,10 +1398,19 @@ static void rtl8168ep_driver_stop(struct
 | 
			
		||||
 		rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8125bp_driver_stop(struct rtl8169_private *tp)
 | 
			
		||||
+{
 | 
			
		||||
+	r8168ep_ocp_write(tp, 0x01, 0x14, OOB_CMD_DRIVER_STOP);
 | 
			
		||||
+	r8168ep_ocp_write(tp, 0x01, 0x18, 0x00);
 | 
			
		||||
+	r8168ep_ocp_write(tp, 0x01, 0x10, 0x01);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void rtl8168_driver_stop(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	if (tp->dash_type == RTL_DASH_DP)
 | 
			
		||||
 		rtl8168dp_driver_stop(tp);
 | 
			
		||||
+	else if (tp->dash_type == RTL_DASH_25_BP)
 | 
			
		||||
+		rtl8125bp_driver_stop(tp);
 | 
			
		||||
 	else
 | 
			
		||||
 		rtl8168ep_driver_stop(tp);
 | 
			
		||||
 }
 | 
			
		||||
@@ -1411,6 +1433,7 @@ static bool rtl_dash_is_enabled(struct r
 | 
			
		||||
 	case RTL_DASH_DP:
 | 
			
		||||
 		return r8168dp_check_dash(tp);
 | 
			
		||||
 	case RTL_DASH_EP:
 | 
			
		||||
+	case RTL_DASH_25_BP:
 | 
			
		||||
 		return r8168ep_check_dash(tp);
 | 
			
		||||
 	default:
 | 
			
		||||
 		return false;
 | 
			
		||||
@@ -1425,6 +1448,8 @@ static enum rtl_dash_type rtl_get_dash_t
 | 
			
		||||
 		return RTL_DASH_DP;
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53:
 | 
			
		||||
 		return RTL_DASH_EP;
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
+		return RTL_DASH_25_BP;
 | 
			
		||||
 	default:
 | 
			
		||||
 		return RTL_DASH_NONE;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -2261,6 +2286,9 @@ static enum mac_version rtl8169_get_mac_
 | 
			
		||||
 		{ 0x7cf, 0x64a,	RTL_GIGA_MAC_VER_71 },
 | 
			
		||||
 		{ 0x7cf, 0x649,	RTL_GIGA_MAC_VER_70 },
 | 
			
		||||
 
 | 
			
		||||
+		/* 8125BP family. */
 | 
			
		||||
+		{ 0x7cf, 0x681,	RTL_GIGA_MAC_VER_66 },
 | 
			
		||||
+
 | 
			
		||||
 		/* 8125D family. */
 | 
			
		||||
 		{ 0x7cf, 0x689,	RTL_GIGA_MAC_VER_65 },
 | 
			
		||||
 		{ 0x7cf, 0x688,	RTL_GIGA_MAC_VER_64 },
 | 
			
		||||
@@ -3844,6 +3872,7 @@ static void rtl_hw_config(struct rtl8169
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_64] = rtl_hw_start_8125d,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_65] = rtl_hw_start_8125d,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_66] = rtl_hw_start_8125d,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_70] = rtl_hw_start_8126a,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_71] = rtl_hw_start_8126a,
 | 
			
		||||
 	};
 | 
			
		||||
@@ -3863,6 +3892,7 @@ static void rtl_hw_start_8125(struct rtl
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_61:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_64:
 | 
			
		||||
 	case RTL_GIGA_MAC_VER_65:
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_66:
 | 
			
		||||
 		for (i = 0xa00; i < 0xb00; i += 4)
 | 
			
		||||
 			RTL_W32(tp, i, 0);
 | 
			
		||||
 		break;
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
 | 
			
		||||
@@ -1102,6 +1102,28 @@ static void rtl8125d_hw_phy_config(struc
 | 
			
		||||
 	rtl8125_config_eee_phy(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void rtl8125bp_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
+				    struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	r8169_apply_firmware(tp);
 | 
			
		||||
+	rtl8168g_enable_gphy_10m(phydev);
 | 
			
		||||
+
 | 
			
		||||
+	r8168g_phy_param(phydev, 0x8010, 0x0800, 0x0000);
 | 
			
		||||
+
 | 
			
		||||
+	phy_write(phydev, 0x1f, 0x0b87);
 | 
			
		||||
+	phy_write(phydev, 0x16, 0x8088);
 | 
			
		||||
+	phy_modify(phydev, 0x17, 0xff00, 0x9000);
 | 
			
		||||
+	phy_write(phydev, 0x16, 0x808f);
 | 
			
		||||
+	phy_modify(phydev, 0x17, 0xff00, 0x9000);
 | 
			
		||||
+	phy_write(phydev, 0x1f, 0x0000);
 | 
			
		||||
+
 | 
			
		||||
+	r8168g_phy_param(phydev, 0x8174, 0x2000, 0x1800);
 | 
			
		||||
+
 | 
			
		||||
+	rtl8125_legacy_force_mode(phydev);
 | 
			
		||||
+	rtl8168g_disable_aldps(phydev);
 | 
			
		||||
+	rtl8125_config_eee_phy(phydev);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
 | 
			
		||||
 				   struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1163,6 +1185,7 @@ void r8169_hw_phy_config(struct rtl8169_
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_64] = rtl8125d_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_65] = rtl8125d_hw_phy_config,
 | 
			
		||||
+		[RTL_GIGA_MAC_VER_66] = rtl8125bp_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_70] = rtl8126a_hw_phy_config,
 | 
			
		||||
 		[RTL_GIGA_MAC_VER_71] = rtl8126a_hw_phy_config,
 | 
			
		||||
 	};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
From f87a17ed3b51fba4dfdd8f8b643b5423a85fc551 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Tue, 15 Oct 2024 07:47:14 +0200
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: merge the drivers for internal NBase-T
 | 
			
		||||
 PHY's
 | 
			
		||||
 | 
			
		||||
The Realtek RTL8125/RTL8126 NBase-T MAC/PHY chips have internal PHY's
 | 
			
		||||
which are register-compatible, at least for the registers we use here.
 | 
			
		||||
So let's use just one PHY driver to support all of them.
 | 
			
		||||
These internal PHY's exist also as external C45 PHY's, but on the
 | 
			
		||||
internal PHY's no access to MMD registers is possible. This can be
 | 
			
		||||
used to differentiate between the internal and external version.
 | 
			
		||||
 | 
			
		||||
As a side effect the drivers for two now external-only drivers don't
 | 
			
		||||
require read_mmd/write_mmd hooks any longer.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Link: https://patch.msgid.link/c57081a6-811f-4571-ab35-34f4ca6de9af@gmail.com
 | 
			
		||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 53 +++++++++++++++++++++++++++++++--------
 | 
			
		||||
 1 file changed, 43 insertions(+), 10 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -95,6 +95,7 @@
 | 
			
		||||
 
 | 
			
		||||
 #define RTL_GENERIC_PHYID			0x001cc800
 | 
			
		||||
 #define RTL_8211FVD_PHYID			0x001cc878
 | 
			
		||||
+#define RTL_8221B				0x001cc840
 | 
			
		||||
 #define RTL_8221B_VB_CG				0x001cc849
 | 
			
		||||
 #define RTL_8221B_VN_CG				0x001cc84a
 | 
			
		||||
 #define RTL_8251B				0x001cc862
 | 
			
		||||
@@ -1077,6 +1078,23 @@ static bool rtlgen_supports_2_5gbps(stru
 | 
			
		||||
 	return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+/* On internal PHY's MMD reads over C22 always return 0.
 | 
			
		||||
+ * Check a MMD register which is known to be non-zero.
 | 
			
		||||
+ */
 | 
			
		||||
+static bool rtlgen_supports_mmd(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	int val;
 | 
			
		||||
+
 | 
			
		||||
+	phy_lock_mdio_bus(phydev);
 | 
			
		||||
+	__phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS);
 | 
			
		||||
+	__phy_write(phydev, MII_MMD_DATA, MDIO_PCS_EEE_ABLE);
 | 
			
		||||
+	__phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS | MII_MMD_CTRL_NOINCR);
 | 
			
		||||
+	val = __phy_read(phydev, MII_MMD_DATA);
 | 
			
		||||
+	phy_unlock_mdio_bus(phydev);
 | 
			
		||||
+
 | 
			
		||||
+	return val > 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int rtlgen_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	return phydev->phy_id == RTL_GENERIC_PHYID &&
 | 
			
		||||
@@ -1086,7 +1104,8 @@ static int rtlgen_match_phy_device(struc
 | 
			
		||||
 static int rtl8226_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	return phydev->phy_id == RTL_GENERIC_PHYID &&
 | 
			
		||||
-	       rtlgen_supports_2_5gbps(phydev);
 | 
			
		||||
+	       rtlgen_supports_2_5gbps(phydev) &&
 | 
			
		||||
+	       rtlgen_supports_mmd(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
 | 
			
		||||
@@ -1098,6 +1117,11 @@ static int rtlgen_is_c45_match(struct ph
 | 
			
		||||
 		return !is_c45 && (id == phydev->phy_id);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int rtl8221b_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
 | 
			
		||||
@@ -1118,9 +1142,21 @@ static int rtl8221b_vn_cg_c45_match_phy_
 | 
			
		||||
 	return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int rtl8251b_c22_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
+static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
-	return rtlgen_is_c45_match(phydev, RTL_8251B, false);
 | 
			
		||||
+	if (phydev->is_c45)
 | 
			
		||||
+		return false;
 | 
			
		||||
+
 | 
			
		||||
+	switch (phydev->phy_id) {
 | 
			
		||||
+	case RTL_GENERIC_PHYID:
 | 
			
		||||
+	case RTL_8221B:
 | 
			
		||||
+	case RTL_8251B:
 | 
			
		||||
+		break;
 | 
			
		||||
+	default:
 | 
			
		||||
+		return false;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
@@ -1382,10 +1418,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 		.resume		= rtlgen_resume,
 | 
			
		||||
 		.read_page	= rtl821x_read_page,
 | 
			
		||||
 		.write_page	= rtl821x_write_page,
 | 
			
		||||
-		.read_mmd	= rtl822x_read_mmd,
 | 
			
		||||
-		.write_mmd	= rtl822x_write_mmd,
 | 
			
		||||
 	}, {
 | 
			
		||||
-		PHY_ID_MATCH_EXACT(0x001cc840),
 | 
			
		||||
+		.match_phy_device = rtl8221b_match_phy_device,
 | 
			
		||||
 		.name		= "RTL8226B_RTL8221B 2.5Gbps PHY",
 | 
			
		||||
 		.get_features	= rtl822x_get_features,
 | 
			
		||||
 		.config_aneg	= rtl822x_config_aneg,
 | 
			
		||||
@@ -1396,8 +1430,6 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 		.resume		= rtlgen_resume,
 | 
			
		||||
 		.read_page	= rtl821x_read_page,
 | 
			
		||||
 		.write_page	= rtl821x_write_page,
 | 
			
		||||
-		.read_mmd	= rtl822x_read_mmd,
 | 
			
		||||
-		.write_mmd	= rtl822x_write_mmd,
 | 
			
		||||
 	}, {
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x001cc838),
 | 
			
		||||
 		.name           = "RTL8226-CG 2.5Gbps PHY",
 | 
			
		||||
@@ -1475,8 +1507,9 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 		.read_page      = rtl821x_read_page,
 | 
			
		||||
 		.write_page     = rtl821x_write_page,
 | 
			
		||||
 	}, {
 | 
			
		||||
-		.match_phy_device = rtl8251b_c22_match_phy_device,
 | 
			
		||||
-		.name           = "RTL8126A-internal 5Gbps PHY",
 | 
			
		||||
+		.match_phy_device = rtl_internal_nbaset_match_phy_device,
 | 
			
		||||
+		.name           = "Realtek Internal NBASE-T PHY",
 | 
			
		||||
+		.flags		= PHY_IS_INTERNAL,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.read_status    = rtl822x_read_status,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
From 8989bad541133c43550bff2b80edbe37b8fb9659 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Thu, 17 Oct 2024 18:01:13 +0200
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: add RTL8125D-internal PHY
 | 
			
		||||
 | 
			
		||||
The first boards show up with Realtek's RTL8125D. This MAC/PHY chip
 | 
			
		||||
comes with an integrated 2.5Gbps PHY with ID 0x001cc841. It's not
 | 
			
		||||
clear yet whether there's an external version of this PHY and how
 | 
			
		||||
Realtek calls it, therefore use the numeric id for now.
 | 
			
		||||
 | 
			
		||||
Link: https://lore.kernel.org/netdev/2ada65e1-5dfa-456c-9334-2bc51272e9da@gmail.com/T/
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Message-ID: <7d2924de-053b-44d2-a479-870dc3878170@gmail.com>
 | 
			
		||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1151,6 +1151,7 @@ static int rtl_internal_nbaset_match_phy
 | 
			
		||||
 	case RTL_GENERIC_PHYID:
 | 
			
		||||
 	case RTL_8221B:
 | 
			
		||||
 	case RTL_8251B:
 | 
			
		||||
+	case 0x001cc841:
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
 		return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
From 34d5a86ff7bbe225fba3ad91f9b4dc85fb408e18 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Wed, 15 Jan 2025 14:43:35 +0000
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: clear 1000Base-T lpa if link is down
 | 
			
		||||
 | 
			
		||||
Only read 1000Base-T link partner advertisement if autonegotiation has
 | 
			
		||||
completed and otherwise 1000Base-T link partner advertisement bits.
 | 
			
		||||
 | 
			
		||||
This fixes bogus 1000Base-T link partner advertisement after link goes
 | 
			
		||||
down (eg. by disconnecting the wire).
 | 
			
		||||
Fixes: 5cb409b3960e ("net: phy: realtek: clear 1000Base-T link partner advertisement")
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 19 ++++++++-----------
 | 
			
		||||
 1 file changed, 8 insertions(+), 11 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1023,23 +1023,20 @@ static int rtl822x_c45_read_status(struc
 | 
			
		||||
 {
 | 
			
		||||
 	int ret, val;
 | 
			
		||||
 
 | 
			
		||||
-	ret = genphy_c45_read_status(phydev);
 | 
			
		||||
-	if (ret < 0)
 | 
			
		||||
-		return ret;
 | 
			
		||||
-
 | 
			
		||||
-	if (phydev->autoneg == AUTONEG_DISABLE ||
 | 
			
		||||
-	    !genphy_c45_aneg_done(phydev))
 | 
			
		||||
-		mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
 | 
			
		||||
-
 | 
			
		||||
 	/* Vendor register as C45 has no standardized support for 1000BaseT */
 | 
			
		||||
-	if (phydev->autoneg == AUTONEG_ENABLE) {
 | 
			
		||||
+	if (phydev->autoneg == AUTONEG_ENABLE && genphy_c45_aneg_done(phydev)) {
 | 
			
		||||
 		val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
 | 
			
		||||
 				   RTL822X_VND2_GANLPAR);
 | 
			
		||||
 		if (val < 0)
 | 
			
		||||
 			return val;
 | 
			
		||||
-
 | 
			
		||||
-		mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		val = 0;
 | 
			
		||||
 	}
 | 
			
		||||
+	mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
 | 
			
		||||
+
 | 
			
		||||
+	ret = genphy_c45_read_status(phydev);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
 
 | 
			
		||||
 	if (!phydev->link)
 | 
			
		||||
 		return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
From ea8318cb33e593bbfc59d637eae45a69732c5387 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Wed, 15 Jan 2025 14:43:43 +0000
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: clear master_slave_state if link is down
 | 
			
		||||
 | 
			
		||||
rtlgen_decode_physr() which sets master_slave_state isn't called in case
 | 
			
		||||
the link is down and other than rtlgen_read_status(),
 | 
			
		||||
rtl822x_c45_read_status() doesn't implicitely clear master_slave_state.
 | 
			
		||||
 | 
			
		||||
Avoid stale master_slave_state by always setting it to
 | 
			
		||||
MASTER_SLAVE_STATE_UNKNOWN in rtl822x_c45_read_status() in case the link
 | 
			
		||||
is down.
 | 
			
		||||
 | 
			
		||||
Fixes: 081c9c0265c9 ("net: phy: realtek: read duplex and gbit master from PHYSR register")
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 4 +++-
 | 
			
		||||
 1 file changed, 3 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1038,8 +1038,10 @@ static int rtl822x_c45_read_status(struc
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	if (!phydev->link)
 | 
			
		||||
+	if (!phydev->link) {
 | 
			
		||||
+		phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
 | 
			
		||||
 		return 0;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Read actual speed from vendor register. */
 | 
			
		||||
 	val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL_VND2_PHYSR);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
From d3eb58549842c60ed46f37da7f4da969e3d6ecd3 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Wed, 15 Jan 2025 14:45:00 +0000
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: always clear NBase-T lpa
 | 
			
		||||
 | 
			
		||||
Clear NBase-T link partner advertisement before calling
 | 
			
		||||
rtlgen_read_status() to avoid phy_resolve_aneg_linkmode() wrongly
 | 
			
		||||
setting speed and duplex.
 | 
			
		||||
 | 
			
		||||
This fixes bogus 2.5G/5G/10G link partner advertisement and thus
 | 
			
		||||
speed and duplex being set by phy_resolve_aneg_linkmode() due to stale
 | 
			
		||||
NBase-T lpa.
 | 
			
		||||
 | 
			
		||||
Fixes: 68d5cd09e891 ("net: phy: realtek: change order of calls in C22 read_status()")
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 6 +++---
 | 
			
		||||
 1 file changed, 3 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -952,15 +952,15 @@ static int rtl822x_read_status(struct ph
 | 
			
		||||
 {
 | 
			
		||||
 	int lpadv, ret;
 | 
			
		||||
 
 | 
			
		||||
+	mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
 | 
			
		||||
+
 | 
			
		||||
 	ret = rtlgen_read_status(phydev);
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
 	if (phydev->autoneg == AUTONEG_DISABLE ||
 | 
			
		||||
-	    !phydev->autoneg_complete) {
 | 
			
		||||
-		mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
 | 
			
		||||
+	    !phydev->autoneg_complete)
 | 
			
		||||
 		return 0;
 | 
			
		||||
-	}
 | 
			
		||||
 
 | 
			
		||||
 	lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
 | 
			
		||||
 	if (lpadv < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
From 3d483a10327f38595f714f9f9e9dde43a622cb0f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Sat, 11 Jan 2025 21:49:31 +0100
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: add support for reading MDIO_MMD_VEND2
 | 
			
		||||
 regs on RTL8125/RTL8126
 | 
			
		||||
 | 
			
		||||
RTL8125/RTL8126 don't support MMD access to the internal PHY, but
 | 
			
		||||
provide a mechanism to access at least all MDIO_MMD_VEND2 registers.
 | 
			
		||||
By exposing this mechanism standard MMD access functions can be used
 | 
			
		||||
to access the MDIO_MMD_VEND2 registers.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
Link: https://patch.msgid.link/e821b302-5fe6-49ab-aabd-05da500581c0@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 12 ++++++++++--
 | 
			
		||||
 1 file changed, 10 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -736,7 +736,11 @@ static int rtlgen_read_mmd(struct phy_de
 | 
			
		||||
 {
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
-	if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
 | 
			
		||||
+	if (devnum == MDIO_MMD_VEND2) {
 | 
			
		||||
+		rtl821x_write_page(phydev, regnum >> 4);
 | 
			
		||||
+		ret = __phy_read(phydev, 0x10 + ((regnum & 0xf) >> 1));
 | 
			
		||||
+		rtl821x_write_page(phydev, 0);
 | 
			
		||||
+	} else if (devnum == MDIO_MMD_PCS && regnum == MDIO_PCS_EEE_ABLE) {
 | 
			
		||||
 		rtl821x_write_page(phydev, 0xa5c);
 | 
			
		||||
 		ret = __phy_read(phydev, 0x12);
 | 
			
		||||
 		rtl821x_write_page(phydev, 0);
 | 
			
		||||
@@ -760,7 +764,11 @@ static int rtlgen_write_mmd(struct phy_d
 | 
			
		||||
 {
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
-	if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
 | 
			
		||||
+	if (devnum == MDIO_MMD_VEND2) {
 | 
			
		||||
+		rtl821x_write_page(phydev, regnum >> 4);
 | 
			
		||||
+		ret = __phy_write(phydev, 0x10 + ((regnum & 0xf) >> 1), val);
 | 
			
		||||
+		rtl821x_write_page(phydev, 0);
 | 
			
		||||
+	} else if (devnum == MDIO_MMD_AN && regnum == MDIO_AN_EEE_ADV) {
 | 
			
		||||
 		rtl821x_write_page(phydev, 0xa5d);
 | 
			
		||||
 		ret = __phy_write(phydev, 0x10, val);
 | 
			
		||||
 		rtl821x_write_page(phydev, 0);
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,180 @@
 | 
			
		|||
From 33700ca45b7d2e1655d4cad95e25671e8a94e2f0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Sat, 11 Jan 2025 21:51:24 +0100
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: add hwmon support for temp sensor on
 | 
			
		||||
 RTL822x
 | 
			
		||||
 | 
			
		||||
This adds hwmon support for the temperature sensor on RTL822x.
 | 
			
		||||
It's available on the standalone versions of the PHY's, and on
 | 
			
		||||
the integrated PHY's in RTL8125B/RTL8125D/RTL8126.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
Link: https://patch.msgid.link/ad6bfe9f-6375-4a00-84b4-bfb38a21bd71@gmail.com
 | 
			
		||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek/Kconfig         |  6 ++
 | 
			
		||||
 drivers/net/phy/realtek/Makefile        |  1 +
 | 
			
		||||
 drivers/net/phy/realtek/realtek.h       | 10 ++++
 | 
			
		||||
 drivers/net/phy/realtek/realtek_hwmon.c | 79 +++++++++++++++++++++++++
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c  | 12 ++++
 | 
			
		||||
 5 files changed, 108 insertions(+)
 | 
			
		||||
 create mode 100644 drivers/net/phy/realtek/realtek.h
 | 
			
		||||
 create mode 100644 drivers/net/phy/realtek/realtek_hwmon.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek/Kconfig
 | 
			
		||||
+++ b/drivers/net/phy/realtek/Kconfig
 | 
			
		||||
@@ -3,3 +3,9 @@ config REALTEK_PHY
 | 
			
		||||
 	tristate "Realtek PHYs"
 | 
			
		||||
 	help
 | 
			
		||||
 	  Currently supports RTL821x/RTL822x and fast ethernet PHYs
 | 
			
		||||
+
 | 
			
		||||
+config REALTEK_PHY_HWMON
 | 
			
		||||
+	def_bool REALTEK_PHY && HWMON
 | 
			
		||||
+	depends on !(REALTEK_PHY=y && HWMON=m)
 | 
			
		||||
+	help
 | 
			
		||||
+	  Optional hwmon support for the temperature sensor
 | 
			
		||||
--- a/drivers/net/phy/realtek/Makefile
 | 
			
		||||
+++ b/drivers/net/phy/realtek/Makefile
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
 # SPDX-License-Identifier: GPL-2.0
 | 
			
		||||
 realtek-y			+= realtek_main.o
 | 
			
		||||
+realtek-$(CONFIG_REALTEK_PHY_HWMON) += realtek_hwmon.o
 | 
			
		||||
 obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek.h
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
+/* SPDX-License-Identifier: GPL-2.0 */
 | 
			
		||||
+
 | 
			
		||||
+#ifndef REALTEK_H
 | 
			
		||||
+#define REALTEK_H
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/phy.h>
 | 
			
		||||
+
 | 
			
		||||
+int rtl822x_hwmon_init(struct phy_device *phydev);
 | 
			
		||||
+
 | 
			
		||||
+#endif /* REALTEK_H */
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_hwmon.c
 | 
			
		||||
@@ -0,0 +1,86 @@
 | 
			
		||||
+// SPDX-License-Identifier: GPL-2.0+
 | 
			
		||||
+/*
 | 
			
		||||
+ * HWMON support for Realtek PHY's
 | 
			
		||||
+ *
 | 
			
		||||
+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/hwmon.h>
 | 
			
		||||
+#include <linux/phy.h>
 | 
			
		||||
+
 | 
			
		||||
+#include "realtek.h"
 | 
			
		||||
+
 | 
			
		||||
+#define RTL822X_VND2_TSALRM				0xa662
 | 
			
		||||
+#define RTL822X_VND2_TSRR				0xbd84
 | 
			
		||||
+#define RTL822X_VND2_TSSR				0xb54c
 | 
			
		||||
+
 | 
			
		||||
+static umode_t rtl822x_hwmon_is_visible(const void *drvdata,
 | 
			
		||||
+				        enum hwmon_sensor_types type,
 | 
			
		||||
+				        u32 attr, int channel)
 | 
			
		||||
+{
 | 
			
		||||
+	return 0444;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int rtl822x_hwmon_get_temp(int raw)
 | 
			
		||||
+{
 | 
			
		||||
+	if (raw >= 512)
 | 
			
		||||
+		raw -= 1024;
 | 
			
		||||
+
 | 
			
		||||
+	return 1000 * raw / 2;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int rtl822x_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
 | 
			
		||||
+			      u32 attr, int channel, long *val)
 | 
			
		||||
+{
 | 
			
		||||
+	struct phy_device *phydev = dev_get_drvdata(dev);
 | 
			
		||||
+	int raw;
 | 
			
		||||
+
 | 
			
		||||
+	switch (attr) {
 | 
			
		||||
+	case hwmon_temp_input:
 | 
			
		||||
+		raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSRR) & 0x3ff;
 | 
			
		||||
+		*val = rtl822x_hwmon_get_temp(raw);
 | 
			
		||||
+		break;
 | 
			
		||||
+	case hwmon_temp_max:
 | 
			
		||||
+		/* Chip reduces speed to 1G if threshold is exceeded */
 | 
			
		||||
+		raw = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSSR) >> 6;
 | 
			
		||||
+		*val = rtl822x_hwmon_get_temp(raw);
 | 
			
		||||
+		break;
 | 
			
		||||
+	default:
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static const struct hwmon_ops rtl822x_hwmon_ops = {
 | 
			
		||||
+	.is_visible = rtl822x_hwmon_is_visible,
 | 
			
		||||
+	.read = rtl822x_hwmon_read,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const struct hwmon_channel_info * const rtl822x_hwmon_info[] = {
 | 
			
		||||
+	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX),
 | 
			
		||||
+	NULL
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const struct hwmon_chip_info rtl822x_hwmon_chip_info = {
 | 
			
		||||
+	.ops = &rtl822x_hwmon_ops,
 | 
			
		||||
+	.info = rtl822x_hwmon_info,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+int rtl822x_hwmon_init(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device *hwdev, *dev = &phydev->mdio.dev;
 | 
			
		||||
+	const char *name;
 | 
			
		||||
+
 | 
			
		||||
+	/* Ensure over-temp alarm is reset. */
 | 
			
		||||
+	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_TSALRM, 3);
 | 
			
		||||
+
 | 
			
		||||
+	name = devm_hwmon_sanitize_name(dev, dev_name(dev));
 | 
			
		||||
+	if (IS_ERR(name))
 | 
			
		||||
+		return PTR_ERR(name);
 | 
			
		||||
+
 | 
			
		||||
+	hwdev = devm_hwmon_device_register_with_info(dev, name, phydev,
 | 
			
		||||
+						     &rtl822x_hwmon_chip_info,
 | 
			
		||||
+						     NULL);
 | 
			
		||||
+	return PTR_ERR_OR_ZERO(hwdev);
 | 
			
		||||
+}
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -14,6 +14,8 @@
 | 
			
		||||
 #include <linux/delay.h>
 | 
			
		||||
 #include <linux/clk.h>
 | 
			
		||||
 
 | 
			
		||||
+#include "realtek.h"
 | 
			
		||||
+
 | 
			
		||||
 #define RTL821x_PHYSR				0x11
 | 
			
		||||
 #define RTL821x_PHYSR_DUPLEX			BIT(13)
 | 
			
		||||
 #define RTL821x_PHYSR_SPEED			GENMASK(15, 14)
 | 
			
		||||
@@ -820,6 +822,15 @@ static int rtl822x_write_mmd(struct phy_
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int rtl822x_probe(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	if (IS_ENABLED(CONFIG_REALTEK_PHY_HWMON) &&
 | 
			
		||||
+	    phydev->phy_id != RTL_GENERIC_PHYID)
 | 
			
		||||
+		return rtl822x_hwmon_init(phydev);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int rtl822xb_config_init(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	bool has_2500, has_sgmii;
 | 
			
		||||
@@ -1518,6 +1529,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 		.match_phy_device = rtl_internal_nbaset_match_phy_device,
 | 
			
		||||
 		.name           = "Realtek Internal NBASE-T PHY",
 | 
			
		||||
 		.flags		= PHY_IS_INTERNAL,
 | 
			
		||||
+		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.read_status    = rtl822x_read_status,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
From 64ff63aeefb03139ae27454bd4208244579ae88e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Aleksander Jan Bajkowski <olek2@wp.pl>
 | 
			
		||||
Date: Fri, 17 Jan 2025 23:24:21 +0100
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: HWMON support for standalone versions of
 | 
			
		||||
 RTL8221B and RTL8251
 | 
			
		||||
 | 
			
		||||
HWMON support has been added for the RTL8221/8251 PHYs integrated together
 | 
			
		||||
with the MAC inside the RTL8125/8126 chips. This patch extends temperature
 | 
			
		||||
reading support for standalone variants of the mentioned PHYs.
 | 
			
		||||
 | 
			
		||||
I don't know whether the earlier revisions of the RTL8226 also have a
 | 
			
		||||
built-in temperature sensor, so they have been skipped for now.
 | 
			
		||||
 | 
			
		||||
Tested on RTL8221B-VB-CG.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
 | 
			
		||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 5 +++++
 | 
			
		||||
 1 file changed, 5 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -1474,6 +1474,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1486,6 +1487,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.probe		= rtl822x_probe,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
 		.get_features   = rtl822x_c45_get_features,
 | 
			
		||||
@@ -1496,6 +1498,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1508,6 +1511,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.probe		= rtl822x_probe,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
 		.get_features   = rtl822x_c45_get_features,
 | 
			
		||||
@@ -1518,6 +1522,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8251b_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8251B 5Gbps PHY",
 | 
			
		||||
+		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.read_status    = rtl822x_read_status,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
From b0fa00fe38f673c986633c11087274deeb7ce7b0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Sander Vanheule <sander@svanheule.net>
 | 
			
		||||
Date: Tue, 7 Jan 2025 21:16:20 +0100
 | 
			
		||||
Subject: [PATCH] gpio: regmap: Use generic request/free ops
 | 
			
		||||
 | 
			
		||||
Set the gpiochip request and free ops to the generic implementations.
 | 
			
		||||
This way a user can provide a gpio-ranges property defined for a pinmux,
 | 
			
		||||
easing muxing of gpio functions. Provided that the pin controller
 | 
			
		||||
implementents the pinmux op .gpio_request_enable(), pins will
 | 
			
		||||
automatically be muxed to their GPIO function when requested.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Sander Vanheule <sander@svanheule.net>
 | 
			
		||||
Acked-by: Michael Walle <mwalle@kernel.org>
 | 
			
		||||
Link: https://lore.kernel.org/r/20250107201621.12467-1-sander@svanheule.net
 | 
			
		||||
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpio/gpio-regmap.c | 2 ++
 | 
			
		||||
 1 file changed, 2 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpio/gpio-regmap.c
 | 
			
		||||
+++ b/drivers/gpio/gpio-regmap.c
 | 
			
		||||
@@ -262,6 +262,8 @@ struct gpio_regmap *gpio_regmap_register
 | 
			
		||||
 	chip->label = config->label ?: dev_name(config->parent);
 | 
			
		||||
 	chip->can_sleep = regmap_might_sleep(config->regmap);
 | 
			
		||||
 
 | 
			
		||||
+	chip->request = gpiochip_generic_request;
 | 
			
		||||
+	chip->free = gpiochip_generic_free;
 | 
			
		||||
 	chip->get = gpio_regmap_get;
 | 
			
		||||
 	if (gpio->reg_set_base && gpio->reg_clr_base)
 | 
			
		||||
 		chip->set = gpio_regmap_set_with_clear;
 | 
			
		||||
| 
						 | 
				
			
			@ -8519,3 +8519,4 @@ CONFIG_PROC_MEM_ALWAYS_FORCE=y
 | 
			
		|||
# CONFIG_INSPUR_PLATFORM_PROFILE is not set
 | 
			
		||||
# CONFIG_LENOVO_WMI_CAMERA is not set
 | 
			
		||||
# CONFIG_IMX_SCMI_MISC_DRV is not set
 | 
			
		||||
# CONFIG_NVMEM_LAYOUT_ASCII_ENV is not set
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,8 +19,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
+
 | 
			
		||||
 #endif /* __KERNEL__ */
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
@@ -314,6 +316,4 @@ static inline void *offset_to_ptr(const
 | 
			
		||||
 /**
 | 
			
		||||
@@ -329,6 +331,4 @@ static inline void *offset_to_ptr(const
 | 
			
		||||
  */
 | 
			
		||||
 #define prevent_tail_call_optimization()	mb()
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,82 +0,0 @@
 | 
			
		|||
From: Tobias Wolf <dev-NTEO@vplace.de>
 | 
			
		||||
Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation
 | 
			
		||||
 | 
			
		||||
An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any
 | 
			
		||||
kernel beyond version 4.3 resulting in:
 | 
			
		||||
 | 
			
		||||
BUG: Bad page state in process swapper  pfn:086ac
 | 
			
		||||
 | 
			
		||||
bisect resulted in:
 | 
			
		||||
 | 
			
		||||
a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit
 | 
			
		||||
commit a1c34a3bf00af2cede839879502e12dc68491ad5
 | 
			
		||||
Author: Laura Abbott <laura@labbott.name>
 | 
			
		||||
Date:   Thu Nov 5 18:48:46 2015 -0800
 | 
			
		||||
 | 
			
		||||
    mm: Don't offset memmap for flatmem
 | 
			
		||||
 | 
			
		||||
    Srinivas Kandagatla reported bad page messages when trying to remove the
 | 
			
		||||
    bottom 2MB on an ARM based IFC6410 board
 | 
			
		||||
 | 
			
		||||
      BUG: Bad page state in process swapper  pfn:fffa8
 | 
			
		||||
      page:ef7fb500 count:0 mapcount:0 mapping:  (null) index:0x0
 | 
			
		||||
      flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked)
 | 
			
		||||
      page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set
 | 
			
		||||
      bad because of flags:
 | 
			
		||||
      flags: 0x200041(locked|active|mlocked)
 | 
			
		||||
      Modules linked in:
 | 
			
		||||
      CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty
 | 
			
		||||
#816
 | 
			
		||||
      Hardware name: Qualcomm (Flattened Device Tree)
 | 
			
		||||
        unwind_backtrace
 | 
			
		||||
        show_stack
 | 
			
		||||
        dump_stack
 | 
			
		||||
        bad_page
 | 
			
		||||
        free_pages_prepare
 | 
			
		||||
        free_hot_cold_page
 | 
			
		||||
        __free_pages
 | 
			
		||||
        free_highmem_page
 | 
			
		||||
        mem_init
 | 
			
		||||
        start_kernel
 | 
			
		||||
      Disabling lock debugging due to kernel taint
 | 
			
		||||
    [...]
 | 
			
		||||
:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4
 | 
			
		||||
0a8156f848733dfa21e16c196dfb6c0a76290709 M      mm
 | 
			
		||||
 | 
			
		||||
This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by
 | 
			
		||||
page_to_pfn anymore.
 | 
			
		||||
 | 
			
		||||
The following output was generated with two hacked in printk statements:
 | 
			
		||||
 | 
			
		||||
printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map -
 | 
			
		||||
(pgdat->node_start_pfn - ARCH_PFN_OFFSET));
 | 
			
		||||
		if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
 | 
			
		||||
			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
 | 
			
		||||
printk("after %p\n", mem_map);
 | 
			
		||||
 | 
			
		||||
Output:
 | 
			
		||||
 | 
			
		||||
[    0.000000] before 8861b280 vs. 8861b280 or 8851b280
 | 
			
		||||
[    0.000000] after 8851b280
 | 
			
		||||
 | 
			
		||||
As seen in the first line mem_map with subtraction of offset does not equal the
 | 
			
		||||
mem_map after subtraction of ARCH_PFN_OFFSET.
 | 
			
		||||
 | 
			
		||||
After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the
 | 
			
		||||
previously calculated offset is zero for the named platform it is able to boot
 | 
			
		||||
4.4 and 4.9-rc7 again.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
--- a/mm/mm_init.c
 | 
			
		||||
+++ b/mm/mm_init.c
 | 
			
		||||
@@ -1632,7 +1632,7 @@ static void __init alloc_node_mem_map(st
 | 
			
		||||
 	if (pgdat == NODE_DATA(0)) {
 | 
			
		||||
 		mem_map = NODE_DATA(0)->node_mem_map;
 | 
			
		||||
 		if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
 | 
			
		||||
-			mem_map -= offset;
 | 
			
		||||
+			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
 | 
			
		||||
 	}
 | 
			
		||||
 #endif
 | 
			
		||||
 }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,165 @@
 | 
			
		|||
From: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx
 | 
			
		||||
 | 
			
		||||
[john@phrozen.org: added to my upstream queue 30.12.2016]
 | 
			
		||||
lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed
 | 
			
		||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
---
 | 
			
		||||
 init/Kconfig            | 11 +++++++++++
 | 
			
		||||
 kernel/kallsyms.c       |  8 ++++++++
 | 
			
		||||
 scripts/kallsyms.c      | 12 ++++++++++++
 | 
			
		||||
 scripts/link-vmlinux.sh |  4 ++++
 | 
			
		||||
 4 files changed, 35 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/init/Kconfig
 | 
			
		||||
+++ b/init/Kconfig
 | 
			
		||||
@@ -1525,6 +1525,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW
 | 
			
		||||
 	  the unaligned access emulation.
 | 
			
		||||
 	  see arch/parisc/kernel/unaligned.c for reference
 | 
			
		||||
 
 | 
			
		||||
+config KALLSYMS_UNCOMPRESSED
 | 
			
		||||
+	bool "Keep kallsyms uncompressed"
 | 
			
		||||
+	depends on KALLSYMS
 | 
			
		||||
+	help
 | 
			
		||||
+		Normally kallsyms contains compressed symbols (using a token table),
 | 
			
		||||
+		reducing the uncompressed kernel image size. Keeping the symbol table
 | 
			
		||||
+		uncompressed significantly improves the size of this part in compressed
 | 
			
		||||
+		kernel images.
 | 
			
		||||
+
 | 
			
		||||
+		Say N unless you need compressed kernel images to be small.
 | 
			
		||||
+
 | 
			
		||||
 config HAVE_PCSPKR_PLATFORM
 | 
			
		||||
 	bool
 | 
			
		||||
 
 | 
			
		||||
--- a/kernel/kallsyms.c
 | 
			
		||||
+++ b/kernel/kallsyms.c
 | 
			
		||||
@@ -69,6 +69,11 @@ static unsigned int kallsyms_expand_symb
 | 
			
		||||
 	 * For every byte on the compressed symbol data, copy the table
 | 
			
		||||
 	 * entry for that byte.
 | 
			
		||||
 	 */
 | 
			
		||||
+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
 | 
			
		||||
+	memcpy(result, data + 1, len - 1);
 | 
			
		||||
+	result += len - 1;
 | 
			
		||||
+	len = 0;
 | 
			
		||||
+#endif
 | 
			
		||||
 	while (len) {
 | 
			
		||||
 		tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
 | 
			
		||||
 		data++;
 | 
			
		||||
@@ -101,6 +106,9 @@ tail:
 | 
			
		||||
  */
 | 
			
		||||
 static char kallsyms_get_symbol_type(unsigned int off)
 | 
			
		||||
 {
 | 
			
		||||
+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
 | 
			
		||||
+	return kallsyms_names[off + 1];
 | 
			
		||||
+#endif
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * Get just the first code, look it up in the token table,
 | 
			
		||||
 	 * and return the first char from this token.
 | 
			
		||||
--- a/scripts/kallsyms.c
 | 
			
		||||
+++ b/scripts/kallsyms.c
 | 
			
		||||
@@ -62,6 +62,7 @@ static struct addr_range percpu_range =
 | 
			
		||||
 static struct sym_entry **table;
 | 
			
		||||
 static unsigned int table_size, table_cnt;
 | 
			
		||||
 static int all_symbols;
 | 
			
		||||
+static int uncompressed;
 | 
			
		||||
 static int absolute_percpu;
 | 
			
		||||
 
 | 
			
		||||
 static int token_profit[0x10000];
 | 
			
		||||
@@ -412,12 +413,14 @@ static void write_src(void)
 | 
			
		||||
 		for (k = 0; k < table[i]->len; k++)
 | 
			
		||||
 			printf(", 0x%02x", table[i]->sym[k]);
 | 
			
		||||
 
 | 
			
		||||
-		/*
 | 
			
		||||
-		 * Now that we wrote out the compressed symbol name, restore the
 | 
			
		||||
-		 * original name and print it in the comment.
 | 
			
		||||
-		 */
 | 
			
		||||
-		expand_symbol(table[i]->sym, table[i]->len, buf);
 | 
			
		||||
-		strcpy((char *)table[i]->sym, buf);
 | 
			
		||||
+		if (!uncompressed) {
 | 
			
		||||
+			/*
 | 
			
		||||
+			 * Now that we wrote out the compressed symbol name, restore the
 | 
			
		||||
+			 * original name and print it in the comment.
 | 
			
		||||
+			 */
 | 
			
		||||
+			expand_symbol(table[i]->sym, table[i]->len, buf);
 | 
			
		||||
+			strcpy((char *)table[i]->sym, buf);
 | 
			
		||||
+		}
 | 
			
		||||
 		printf("\t/* %s */\n", table[i]->sym);
 | 
			
		||||
 	}
 | 
			
		||||
 	printf("\n");
 | 
			
		||||
@@ -429,20 +432,22 @@ static void write_src(void)
 | 
			
		||||
 
 | 
			
		||||
 	free(markers);
 | 
			
		||||
 
 | 
			
		||||
-	output_label("kallsyms_token_table");
 | 
			
		||||
-	off = 0;
 | 
			
		||||
-	for (i = 0; i < 256; i++) {
 | 
			
		||||
-		best_idx[i] = off;
 | 
			
		||||
-		expand_symbol(best_table[i], best_table_len[i], buf);
 | 
			
		||||
-		printf("\t.asciz\t\"%s\"\n", buf);
 | 
			
		||||
-		off += strlen(buf) + 1;
 | 
			
		||||
+	if (!uncompressed) {
 | 
			
		||||
+		output_label("kallsyms_token_table");
 | 
			
		||||
+		off = 0;
 | 
			
		||||
+		for (i = 0; i < 256; i++) {
 | 
			
		||||
+			best_idx[i] = off;
 | 
			
		||||
+			expand_symbol(best_table[i], best_table_len[i], buf);
 | 
			
		||||
+			printf("\t.asciz\t\"%s\"\n", buf);
 | 
			
		||||
+			off += strlen(buf) + 1;
 | 
			
		||||
+		}
 | 
			
		||||
+		printf("\n");
 | 
			
		||||
+
 | 
			
		||||
+		output_label("kallsyms_token_index");
 | 
			
		||||
+		for (i = 0; i < 256; i++)
 | 
			
		||||
+			printf("\t.short\t%d\n", best_idx[i]);
 | 
			
		||||
+		printf("\n");
 | 
			
		||||
 	}
 | 
			
		||||
-	printf("\n");
 | 
			
		||||
-
 | 
			
		||||
-	output_label("kallsyms_token_index");
 | 
			
		||||
-	for (i = 0; i < 256; i++)
 | 
			
		||||
-		printf("\t.short\t%d\n", best_idx[i]);
 | 
			
		||||
-	printf("\n");
 | 
			
		||||
 
 | 
			
		||||
 	output_label("kallsyms_offsets");
 | 
			
		||||
 
 | 
			
		||||
@@ -532,6 +537,9 @@ static unsigned char *find_token(unsigne
 | 
			
		||||
 {
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
+	if (uncompressed)
 | 
			
		||||
+		return NULL;
 | 
			
		||||
+
 | 
			
		||||
 	for (i = 0; i < len - 1; i++) {
 | 
			
		||||
 		if (str[i] == token[0] && str[i+1] == token[1])
 | 
			
		||||
 			return &str[i];
 | 
			
		||||
@@ -604,6 +612,9 @@ static void optimize_result(void)
 | 
			
		||||
 {
 | 
			
		||||
 	int i, best;
 | 
			
		||||
 
 | 
			
		||||
+	if (uncompressed)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
 	/* using the '\0' symbol last allows compress_symbols to use standard
 | 
			
		||||
 	 * fast string functions */
 | 
			
		||||
 	for (i = 255; i >= 0; i--) {
 | 
			
		||||
@@ -763,6 +774,7 @@ int main(int argc, char **argv)
 | 
			
		||||
 		static const struct option long_options[] = {
 | 
			
		||||
 			{"all-symbols",     no_argument, &all_symbols,     1},
 | 
			
		||||
 			{"absolute-percpu", no_argument, &absolute_percpu, 1},
 | 
			
		||||
+			{"uncompressed",   no_argument, &uncompressed,   1},
 | 
			
		||||
 			{},
 | 
			
		||||
 		};
 | 
			
		||||
 
 | 
			
		||||
--- a/scripts/link-vmlinux.sh
 | 
			
		||||
+++ b/scripts/link-vmlinux.sh
 | 
			
		||||
@@ -144,6 +144,10 @@ kallsyms()
 | 
			
		||||
 		kallsymopt="${kallsymopt} --absolute-percpu"
 | 
			
		||||
 	fi
 | 
			
		||||
 
 | 
			
		||||
+	if is_enabled CONFIG_KALLSYMS_UNCOMPRESSED; then
 | 
			
		||||
+		kallsymopt="${kallsymopt} --uncompressed"
 | 
			
		||||
+	fi
 | 
			
		||||
+
 | 
			
		||||
 	info KSYMS "${2}.S"
 | 
			
		||||
 	scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S"
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +156,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		|||
+device_initcall(blk_notifications_init);
 | 
			
		||||
--- a/include/linux/blkdev.h
 | 
			
		||||
+++ b/include/linux/blkdev.h
 | 
			
		||||
@@ -1689,4 +1689,15 @@ static inline bool bdev_can_atomic_write
 | 
			
		||||
@@ -1690,4 +1690,15 @@ static inline bool bdev_can_atomic_write
 | 
			
		||||
 
 | 
			
		||||
 #define DEFINE_IO_COMP_BATCH(name)	struct io_comp_batch name = { }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 #define PACKET_FANOUT_LB		1
 | 
			
		||||
--- a/net/packet/af_packet.c
 | 
			
		||||
+++ b/net/packet/af_packet.c
 | 
			
		||||
@@ -1925,6 +1925,7 @@ static int packet_rcv_spkt(struct sk_buf
 | 
			
		||||
@@ -1911,6 +1911,7 @@ static int packet_rcv_spkt(struct sk_buf
 | 
			
		||||
 {
 | 
			
		||||
 	struct sock *sk;
 | 
			
		||||
 	struct sockaddr_pkt *spkt;
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 *	When we registered the protocol we saved the socket in the data
 | 
			
		||||
@@ -1932,6 +1933,7 @@ static int packet_rcv_spkt(struct sk_buf
 | 
			
		||||
@@ -1918,6 +1919,7 @@ static int packet_rcv_spkt(struct sk_buf
 | 
			
		||||
 	 */
 | 
			
		||||
 
 | 
			
		||||
 	sk = pt->af_packet_priv;
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 *	Yank back the headers [hope the device set this
 | 
			
		||||
@@ -1944,7 +1946,7 @@ static int packet_rcv_spkt(struct sk_buf
 | 
			
		||||
@@ -1930,7 +1932,7 @@ static int packet_rcv_spkt(struct sk_buf
 | 
			
		||||
 	 *	so that this procedure is noop.
 | 
			
		||||
 	 */
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 		goto out;
 | 
			
		||||
 
 | 
			
		||||
 	if (!net_eq(dev_net(dev), sock_net(sk)))
 | 
			
		||||
@@ -2189,12 +2191,12 @@ static int packet_rcv(struct sk_buff *sk
 | 
			
		||||
@@ -2175,12 +2177,12 @@ static int packet_rcv(struct sk_buff *sk
 | 
			
		||||
 	int skb_len = skb->len;
 | 
			
		||||
 	unsigned int snaplen, res;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 	if (!net_eq(dev_net(dev), sock_net(sk)))
 | 
			
		||||
 		goto drop;
 | 
			
		||||
 
 | 
			
		||||
@@ -2318,12 +2320,12 @@ static int tpacket_rcv(struct sk_buff *s
 | 
			
		||||
@@ -2304,12 +2306,12 @@ static int tpacket_rcv(struct sk_buff *s
 | 
			
		||||
 	BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
 | 
			
		||||
 	BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 	if (!net_eq(dev_net(dev), sock_net(sk)))
 | 
			
		||||
 		goto drop;
 | 
			
		||||
 
 | 
			
		||||
@@ -3444,6 +3446,7 @@ static int packet_create(struct net *net
 | 
			
		||||
@@ -3430,6 +3432,7 @@ static int packet_create(struct net *net
 | 
			
		||||
 	mutex_init(&po->pg_vec_lock);
 | 
			
		||||
 	po->rollover = NULL;
 | 
			
		||||
 	po->prot_hook.func = packet_rcv;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 
 | 
			
		||||
 	if (sock->type == SOCK_PACKET)
 | 
			
		||||
 		po->prot_hook.func = packet_rcv_spkt;
 | 
			
		||||
@@ -4111,6 +4114,16 @@ packet_setsockopt(struct socket *sock, i
 | 
			
		||||
@@ -4097,6 +4100,16 @@ packet_setsockopt(struct socket *sock, i
 | 
			
		||||
 		packet_sock_flag_set(po, PACKET_SOCK_QDISC_BYPASS, val);
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 	default:
 | 
			
		||||
 		return -ENOPROTOOPT;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -4173,6 +4186,13 @@ static int packet_getsockopt(struct sock
 | 
			
		||||
@@ -4159,6 +4172,13 @@ static int packet_getsockopt(struct sock
 | 
			
		||||
 	case PACKET_COPY_THRESH:
 | 
			
		||||
 		val = READ_ONCE(pkt_sk(sk)->copy_thresh);
 | 
			
		||||
 		break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 }
 | 
			
		||||
--- a/net/core/sock.c
 | 
			
		||||
+++ b/net/core/sock.c
 | 
			
		||||
@@ -2525,7 +2525,7 @@ void sk_setup_caps(struct sock *sk, stru
 | 
			
		||||
@@ -2528,7 +2528,7 @@ void sk_setup_caps(struct sock *sk, stru
 | 
			
		||||
 	if (sk_is_tcp(sk))
 | 
			
		||||
 		sk->sk_route_caps |= NETIF_F_GSO;
 | 
			
		||||
 	if (sk->sk_route_caps & NETIF_F_GSO)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 	if (sk_can_gso(sk)) {
 | 
			
		||||
--- a/net/mac80211/ieee80211_i.h
 | 
			
		||||
+++ b/net/mac80211/ieee80211_i.h
 | 
			
		||||
@@ -2012,7 +2012,7 @@ void ieee80211_color_collision_detection
 | 
			
		||||
@@ -2010,7 +2010,7 @@ void ieee80211_color_collision_detection
 | 
			
		||||
 /* interface handling */
 | 
			
		||||
 #define MAC80211_SUPPORTED_FEATURES_TX	(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
 | 
			
		||||
 					 NETIF_F_HW_CSUM | NETIF_F_SG | \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		|||
 | 
			
		||||
--- a/net/netfilter/nf_tables_api.c
 | 
			
		||||
+++ b/net/netfilter/nf_tables_api.c
 | 
			
		||||
@@ -8607,7 +8607,7 @@ static int nft_register_flowtable_net_ho
 | 
			
		||||
@@ -8615,7 +8615,7 @@ static int nft_register_flowtable_net_ho
 | 
			
		||||
 		err = flowtable->data.type->setup(&flowtable->data,
 | 
			
		||||
 						  hook->ops.dev,
 | 
			
		||||
 						  FLOW_BLOCK_BIND);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,12 +10,12 @@ the PHY.
 | 
			
		|||
Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 6 ++++++
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 6 ++++++
 | 
			
		||||
 1 file changed, 6 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1375,6 +1375,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -1430,6 +1430,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.name		= "RTL8226 2.5Gbps PHY",
 | 
			
		||||
 		.match_phy_device = rtl8226_match_phy_device,
 | 
			
		||||
| 
						 | 
				
			
			@ -23,15 +23,15 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		|||
 		.get_features	= rtl822x_get_features,
 | 
			
		||||
 		.config_aneg	= rtl822x_config_aneg,
 | 
			
		||||
 		.read_status	= rtl822x_read_status,
 | 
			
		||||
@@ -1387,6 +1388,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1440,6 +1441,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x001cc840),
 | 
			
		||||
 		.match_phy_device = rtl8221b_match_phy_device,
 | 
			
		||||
 		.name		= "RTL8226B_RTL8221B 2.5Gbps PHY",
 | 
			
		||||
+		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.get_features	= rtl822x_get_features,
 | 
			
		||||
 		.config_aneg	= rtl822x_config_aneg,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1401,6 +1403,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1452,6 +1454,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x001cc838),
 | 
			
		||||
 		.name           = "RTL8226-CG 2.5Gbps PHY",
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		|||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.read_status    = rtl822x_read_status,
 | 
			
		||||
@@ -1411,6 +1414,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1462,6 +1465,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x001cc848),
 | 
			
		||||
 		.name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
 | 
			
		||||
| 
						 | 
				
			
			@ -47,35 +47,35 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		|||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1423,6 +1427,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1474,6 +1478,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1435,6 +1440,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1487,6 +1492,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
 		.get_features   = rtl822x_c45_get_features,
 | 
			
		||||
@@ -1445,6 +1451,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1498,6 +1504,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1457,6 +1464,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1511,6 +1518,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
 		.get_features   = rtl822x_c45_get_features,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,12 +15,12 @@ Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
 | 
			
		|||
Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 27 +++++++++++++++++++++++++--
 | 
			
		||||
 1 file changed, 25 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -814,8 +814,8 @@ static int rtl822x_write_mmd(struct phy_
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -834,8 +834,8 @@ static int rtl822x_probe(struct phy_devi
 | 
			
		||||
 static int rtl822xb_config_init(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	bool has_2500, has_sgmii;
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		|||
 
 | 
			
		||||
 	has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
 | 
			
		||||
 			    phydev->host_interfaces) ||
 | 
			
		||||
@@ -865,7 +865,29 @@ static int rtl822xb_config_init(struct p
 | 
			
		||||
@@ -885,7 +885,29 @@ static int rtl822xb_config_init(struct p
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,12 +13,12 @@ rtl821x_write_page instead of 3 individually locked MDIO bus operations.
 | 
			
		|||
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 8 +++++---
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 8 +++++---
 | 
			
		||||
 1 file changed, 5 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1092,9 +1092,11 @@ static bool rtlgen_supports_2_5gbps(stru
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -1111,9 +1111,11 @@ static bool rtlgen_supports_2_5gbps(stru
 | 
			
		||||
 {
 | 
			
		||||
 	int val;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,100 +0,0 @@
 | 
			
		|||
From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Sat, 22 Apr 2023 03:26:01 +0100
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
 | 
			
		||||
 | 
			
		||||
Setup Link Down Power Saving Mode according the DTS property
 | 
			
		||||
just like for RTL821x 1GE PHYs.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 11 +++++++++++
 | 
			
		||||
 1 file changed, 11 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -80,6 +80,10 @@
 | 
			
		||||
 
 | 
			
		||||
 #define RTL822X_VND2_GANLPAR				0xa414
 | 
			
		||||
 
 | 
			
		||||
+#define RTL8221B_PHYCR1				0xa430
 | 
			
		||||
+#define RTL8221B_PHYCR1_ALDPS_EN		BIT(2)
 | 
			
		||||
+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN	BIT(12)
 | 
			
		||||
+
 | 
			
		||||
 #define RTL8366RB_POWER_SAVE			0x15
 | 
			
		||||
 #define RTL8366RB_POWER_SAVE_ON			BIT(12)
 | 
			
		||||
 
 | 
			
		||||
@@ -1152,6 +1156,25 @@ static int rtl8251b_c45_match_phy_device
 | 
			
		||||
 	return rtlgen_is_c45_match(phydev, RTL_8251B, true);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int rtl822x_probe(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device *dev = &phydev->mdio.dev;
 | 
			
		||||
+	int val;
 | 
			
		||||
+
 | 
			
		||||
+	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1);
 | 
			
		||||
+	if (val < 0)
 | 
			
		||||
+		return val;
 | 
			
		||||
+
 | 
			
		||||
+	if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
 | 
			
		||||
+		val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
 | 
			
		||||
+	else
 | 
			
		||||
+		val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
 | 
			
		||||
+
 | 
			
		||||
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int rtlgen_resume(struct phy_device *phydev)
 | 
			
		||||
 {
 | 
			
		||||
 	int ret = genphy_resume(phydev);
 | 
			
		||||
@@ -1427,6 +1450,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x001cc838),
 | 
			
		||||
 		.name           = "RTL8226-CG 2.5Gbps PHY",
 | 
			
		||||
+		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
@@ -1438,6 +1462,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x001cc848),
 | 
			
		||||
 		.name           = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
 | 
			
		||||
+		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
@@ -1451,6 +1476,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
@@ -1464,6 +1490,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
@@ -1475,6 +1502,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_config_aneg,
 | 
			
		||||
@@ -1488,6 +1516,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Sat, 22 Apr 2023 03:26:01 +0100
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
 | 
			
		||||
 | 
			
		||||
Setup Link Down Power Saving Mode according the DTS property
 | 
			
		||||
just like for RTL821x 1GE PHYs.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 11 +++++++++++
 | 
			
		||||
 1 file changed, 11 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -82,6 +82,10 @@
 | 
			
		||||
 
 | 
			
		||||
 #define RTL822X_VND2_GANLPAR				0xa414
 | 
			
		||||
 
 | 
			
		||||
+#define RTL8221B_PHYCR1				0xa430
 | 
			
		||||
+#define RTL8221B_PHYCR1_ALDPS_EN		BIT(2)
 | 
			
		||||
+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN	BIT(12)
 | 
			
		||||
+
 | 
			
		||||
 #define RTL8366RB_POWER_SAVE			0x15
 | 
			
		||||
 #define RTL8366RB_POWER_SAVE_ON			BIT(12)
 | 
			
		||||
 
 | 
			
		||||
@@ -889,6 +893,15 @@ static int rtl822xb_config_init(struct p
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
+	if (of_property_read_bool(phydev->mdio.dev.of_node, "realtek,aldps-enable"))
 | 
			
		||||
+		ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1,
 | 
			
		||||
+				 RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
 | 
			
		||||
+	else
 | 
			
		||||
+		ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1,
 | 
			
		||||
+				   RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
 	/* Disable SGMII AN */
 | 
			
		||||
 	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +12,9 @@ over the implemented MMDs.
 | 
			
		|||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
[forward-port by @namiltd]
 | 
			
		||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1120,10 +1120,32 @@ static int rtl8226_match_phy_device(stru
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -1166,10 +1166,32 @@ static int rtl8226_match_phy_device(stru
 | 
			
		||||
 static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
 | 
			
		||||
 			       bool is_c45)
 | 
			
		||||
 {
 | 
			
		||||
| 
						 | 
				
			
			@ -49,4 +49,4 @@ Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
 | 
			
		|||
+	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
 static int rtl8221b_match_phy_device(struct phy_device *phydev)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,12 +7,12 @@ This commit introduces interrupt support for RTL8221B.
 | 
			
		|||
 | 
			
		||||
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 47 +++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 47 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek.c
 | 
			
		||||
@@ -1332,6 +1332,51 @@ static irqreturn_t rtl9000a_handle_inter
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -1377,6 +1377,51 @@ static irqreturn_t rtl9000a_handle_inter
 | 
			
		||||
 	return IRQ_HANDLED;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -64,39 +64,39 @@ Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
 | 
			
		|||
 static struct phy_driver realtek_drvs[] = {
 | 
			
		||||
 	{
 | 
			
		||||
 		PHY_ID_MATCH_EXACT(0x00008201),
 | 
			
		||||
@@ -1498,6 +1543,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1537,6 +1582,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.config_intr	= rtl8221b_config_intr,
 | 
			
		||||
+		.handle_interrupt = rtl8221b_handle_interrupt,
 | 
			
		||||
 		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
@@ -1512,6 +1559,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1551,6 +1598,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.config_intr	= rtl8221b_config_intr,
 | 
			
		||||
+		.handle_interrupt = rtl8221b_handle_interrupt,
 | 
			
		||||
 		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
@@ -1524,6 +1573,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1563,6 +1612,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
 | 
			
		||||
+		.config_intr	= rtl8221b_config_intr,
 | 
			
		||||
+		.handle_interrupt = rtl8221b_handle_interrupt,
 | 
			
		||||
 		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.get_features   = rtl822x_get_features,
 | 
			
		||||
@@ -1538,6 +1589,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
@@ -1577,6 +1628,8 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 	}, {
 | 
			
		||||
 		.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
 | 
			
		||||
 		.name           = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
 | 
			
		||||
+		.config_intr	= rtl8221b_config_intr,
 | 
			
		||||
+		.handle_interrupt = rtl8221b_handle_interrupt,
 | 
			
		||||
 		.probe          = rtl822x_probe,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
 		.config_init    = rtl822xb_config_init,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
From 1addfb042a9d27788a0fb2c2935045b56fd8560e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Thu, 23 Jan 2025 03:25:29 +0000
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: mark existing MMDs as present
 | 
			
		||||
 | 
			
		||||
When using Clause-45 mode to access RealTek RTL8221B 2.5G PHYs some
 | 
			
		||||
versions of the PHY fail to report the MMDs present on the PHY.
 | 
			
		||||
Mark MMDs PMAPMD, PCS and AN which are always existing according to
 | 
			
		||||
the datasheet as present to fix that.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/realtek/realtek_main.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -1043,6 +1043,9 @@ static int rtl822x_c45_get_features(stru
 | 
			
		||||
 	linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
 | 
			
		||||
 			 phydev->supported);
 | 
			
		||||
 
 | 
			
		||||
+	phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
 | 
			
		||||
+				        MDIO_DEVS_AN;
 | 
			
		||||
+
 | 
			
		||||
 	return genphy_c45_pma_read_abilities(phydev);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Thu, 30 Jan 2025 05:33:12 +0000
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: work around broken SerDes
 | 
			
		||||
 | 
			
		||||
For still unknown reasons the SerDes init sequence may sometimes
 | 
			
		||||
time out because a self-clearing bit never clears, indicating the
 | 
			
		||||
PHY has entered an unrecoverable error state.
 | 
			
		||||
 | 
			
		||||
Work-around the issue by triggering a hardware reset and retry the
 | 
			
		||||
setup sequence while warning the user that this has happened.
 | 
			
		||||
This is really more of a work-around than a fix, and should be
 | 
			
		||||
replaced by a better actual fix in future (hopefully).
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -923,6 +923,22 @@ static int rtl822xb_config_init(struct p
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int rtl822xb_config_init_war(struct phy_device *phydev)
 | 
			
		||||
+{
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = rtl822xb_config_init(phydev);
 | 
			
		||||
+
 | 
			
		||||
+	if (ret == -ETIMEDOUT) {
 | 
			
		||||
+		phydev_warn(phydev, "SerDes setup timed out, retrying\n");
 | 
			
		||||
+		phy_device_reset(phydev, 1);
 | 
			
		||||
+		phy_device_reset(phydev, 0);
 | 
			
		||||
+		ret = rtl822xb_config_init(phydev);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int rtl822xb_get_rate_matching(struct phy_device *phydev,
 | 
			
		||||
 				      phy_interface_t iface)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1605,7 +1621,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 		.handle_interrupt = rtl8221b_handle_interrupt,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
-		.config_init    = rtl822xb_config_init,
 | 
			
		||||
+		.config_init    = rtl822xb_config_init_war,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
 		.get_features   = rtl822x_c45_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_c45_config_aneg,
 | 
			
		||||
@@ -1635,7 +1651,7 @@ static struct phy_driver realtek_drvs[]
 | 
			
		||||
 		.handle_interrupt = rtl8221b_handle_interrupt,
 | 
			
		||||
 		.soft_reset     = genphy_soft_reset,
 | 
			
		||||
 		.probe		= rtl822x_probe,
 | 
			
		||||
-		.config_init    = rtl822xb_config_init,
 | 
			
		||||
+		.config_init    = rtl822xb_config_init_war,
 | 
			
		||||
 		.get_rate_matching = rtl822xb_get_rate_matching,
 | 
			
		||||
 		.get_features   = rtl822x_c45_get_features,
 | 
			
		||||
 		.config_aneg    = rtl822x_c45_config_aneg,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
From: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
Date: Thu, 30 Jan 2025 05:38:31 +0000
 | 
			
		||||
Subject: [PATCH] net: phy: realtek: disable MDIO broadcast
 | 
			
		||||
 | 
			
		||||
RealTek's PHYs by default also listen on MDIO address 0 which is defined
 | 
			
		||||
as broadcast address. This can lead to problems if there is an actual PHY
 | 
			
		||||
(such as MT7981 built-in PHY) present at this address, as accessing that
 | 
			
		||||
PHY may then confuse the RealTek PHY.
 | 
			
		||||
 | 
			
		||||
Disabled listening on the MDIO broadcast address to avoid such problems.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | 
			
		||||
---
 | 
			
		||||
--- a/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
+++ b/drivers/net/phy/realtek/realtek_main.c
 | 
			
		||||
@@ -849,6 +849,11 @@ static int rtl822xb_config_init(struct p
 | 
			
		||||
 			     phydev->host_interfaces) ||
 | 
			
		||||
 		    phydev->interface == PHY_INTERFACE_MODE_SGMII;
 | 
			
		||||
 
 | 
			
		||||
+	/* disable listening on MDIO broadcast address (0) */
 | 
			
		||||
+	ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, 0xa430, BIT(13));
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
 	/* fill in possible interfaces */
 | 
			
		||||
 	__assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
 | 
			
		||||
 		     has_2500);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
From: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
Subject: [PATCH net-next 3/4] net: ethernet: mtk_eth_soc: reduce rx ring size for older chipsets
 | 
			
		||||
Date: Tue, 15 Oct 2024 13:09:37 +0200
 | 
			
		||||
 | 
			
		||||
Commit c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer
 | 
			
		||||
size soc specific") resolved some tx timeout issues by bumping FQ and
 | 
			
		||||
tx ring sizes from 512 to 2048 entries (the value used in the MediaTek
 | 
			
		||||
SDK), however it also changed the rx ring size for all chipsets in the
 | 
			
		||||
same way.
 | 
			
		||||
 | 
			
		||||
Based on a few tests, it seems that a symmetric rx/tx ring size of 2048
 | 
			
		||||
really only makes sense on MT7988, which is capable of 10G ethernet links.
 | 
			
		||||
 | 
			
		||||
Older chipsets are typically deployed in systems that are more memory
 | 
			
		||||
constrained and don't actually need the larger rings to handle received
 | 
			
		||||
packets.
 | 
			
		||||
 | 
			
		||||
In order to reduce wasted memory set the ring size based on the SoC to
 | 
			
		||||
the following values:
 | 
			
		||||
- 2048 on MT7988
 | 
			
		||||
- 1024 on MT7986
 | 
			
		||||
- 512 (previous value) on everything else, except:
 | 
			
		||||
- 256 on RT5350 (the oldest supported chipset)
 | 
			
		||||
 | 
			
		||||
Fixes: c57e55819443 ("net: ethernet: mtk_eth_soc: handle dma buffer size soc specific")
 | 
			
		||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++--------
 | 
			
		||||
 1 file changed, 8 insertions(+), 8 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | 
			
		||||
@@ -5387,7 +5387,7 @@ static const struct mtk_soc_data mt2701_
 | 
			
		||||
 		.desc_size = sizeof(struct mtk_rx_dma),
 | 
			
		||||
 		.irq_done_mask = MTK_RX_DONE_INT,
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(512),
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
 	},
 | 
			
		||||
@@ -5415,7 +5415,7 @@ static const struct mtk_soc_data mt7621_
 | 
			
		||||
 		.desc_size = sizeof(struct mtk_rx_dma),
 | 
			
		||||
 		.irq_done_mask = MTK_RX_DONE_INT,
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(512),
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
 	},
 | 
			
		||||
@@ -5445,7 +5445,7 @@ static const struct mtk_soc_data mt7622_
 | 
			
		||||
 		.desc_size = sizeof(struct mtk_rx_dma),
 | 
			
		||||
 		.irq_done_mask = MTK_RX_DONE_INT,
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(512),
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
 	},
 | 
			
		||||
@@ -5474,7 +5474,7 @@ static const struct mtk_soc_data mt7623_
 | 
			
		||||
 		.desc_size = sizeof(struct mtk_rx_dma),
 | 
			
		||||
 		.irq_done_mask = MTK_RX_DONE_INT,
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(512),
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
 	},
 | 
			
		||||
@@ -5500,7 +5500,7 @@ static const struct mtk_soc_data mt7629_
 | 
			
		||||
 		.desc_size = sizeof(struct mtk_rx_dma),
 | 
			
		||||
 		.irq_done_mask = MTK_RX_DONE_INT,
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(512),
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
 	},
 | 
			
		||||
@@ -5532,7 +5532,7 @@ static const struct mtk_soc_data mt7981_
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID_V2,
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(512),
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -5562,7 +5562,7 @@ static const struct mtk_soc_data mt7986_
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID_V2,
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(1K),
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -5615,7 +5615,7 @@ static const struct mtk_soc_data rt5350_
 | 
			
		||||
 		.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
 | 
			
		||||
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 | 
			
		||||
 		.dma_len_offset = 16,
 | 
			
		||||
-		.dma_size = MTK_DMA_SIZE(2K),
 | 
			
		||||
+		.dma_size = MTK_DMA_SIZE(256),
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
From: Danila Romanov <pervokur@gmail.com>
 | 
			
		||||
Date: Wed, 22 Jan 2025 06:48:45 +0100
 | 
			
		||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: do not enable page pool stats by
 | 
			
		||||
 default
 | 
			
		||||
 | 
			
		||||
There is no reason for it to be enabled by default.
 | 
			
		||||
Align mtk_eth_soc driver to mt76 driver.
 | 
			
		||||
 | 
			
		||||
This option incurs additional CPU cost in allocation and recycle paths
 | 
			
		||||
and additional memory cost to store the statistics.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Danila Romanov <pervokur@gmail.com>
 | 
			
		||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/mediatek/Kconfig
 | 
			
		||||
+++ b/drivers/net/ethernet/mediatek/Kconfig
 | 
			
		||||
@@ -26,7 +26,6 @@ config NET_MEDIATEK_SOC
 | 
			
		||||
 	select PHYLINK
 | 
			
		||||
 	select DIMLIB
 | 
			
		||||
 	select PAGE_POOL
 | 
			
		||||
-	select PAGE_POOL_STATS
 | 
			
		||||
 	select PCS_MTK_LYNXI
 | 
			
		||||
 	select REGMAP_MMIO
 | 
			
		||||
 	help
 | 
			
		||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | 
			
		||||
@@ -4552,6 +4552,7 @@ static int mtk_get_sset_count(struct net
 | 
			
		||||
 
 | 
			
		||||
 static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
 | 
			
		||||
 {
 | 
			
		||||
+#ifdef CONFIG_PAGE_POOL_STATS
 | 
			
		||||
 	struct page_pool_stats stats = {};
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
@@ -4564,6 +4565,7 @@ static void mtk_ethtool_pp_stats(struct
 | 
			
		||||
 		page_pool_get_stats(ring->page_pool, &stats);
 | 
			
		||||
 	}
 | 
			
		||||
 	page_pool_ethtool_stats_get(data, &stats);
 | 
			
		||||
+#endif
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void mtk_get_ethtool_stats(struct net_device *dev,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,248 @@
 | 
			
		|||
From fd0e523037439520813db7c57df5bd37cdf40f7e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Christian Marangi <ansuelsmth@gmail.com>
 | 
			
		||||
Date: Mon, 3 Feb 2025 00:10:18 +0100
 | 
			
		||||
Subject: [PATCH 1/2] nvmem: core: generalize "mac-base" cells handling
 | 
			
		||||
 | 
			
		||||
Generalize support of "mac-base" nvmem cells and provide a GPL symbol to
 | 
			
		||||
permit also other NVMEM layout driver to parse mac-base cells.
 | 
			
		||||
 | 
			
		||||
It's VERY COMMON for some specially formatted NVMEM to expose a mac
 | 
			
		||||
address in ASCII format or HEX format hence prevent code duplication by
 | 
			
		||||
exposing a common helper.
 | 
			
		||||
 | 
			
		||||
Such helper will change the nvmem_info_cell and apply the correct post
 | 
			
		||||
process function to correctly parse the mac address.
 | 
			
		||||
 | 
			
		||||
Since the API requires OF and is only related to layout, move the
 | 
			
		||||
function in layouts.c to correctly handle non-OF NVMEM.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/core.c           | 79 +--------------------------------
 | 
			
		||||
 drivers/nvmem/layouts.c        | 80 ++++++++++++++++++++++++++++++++++
 | 
			
		||||
 include/linux/nvmem-provider.h |  4 ++
 | 
			
		||||
 3 files changed, 86 insertions(+), 77 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/core.c
 | 
			
		||||
+++ b/drivers/nvmem/core.c
 | 
			
		||||
@@ -7,12 +7,9 @@
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
 #include <linux/device.h>
 | 
			
		||||
-#include <linux/ctype.h>
 | 
			
		||||
-#include <linux/etherdevice.h>
 | 
			
		||||
 #include <linux/export.h>
 | 
			
		||||
 #include <linux/fs.h>
 | 
			
		||||
 #include <linux/idr.h>
 | 
			
		||||
-#include <linux/if_ether.h>
 | 
			
		||||
 #include <linux/init.h>
 | 
			
		||||
 #include <linux/kref.h>
 | 
			
		||||
 #include <linux/module.h>
 | 
			
		||||
@@ -800,62 +797,6 @@ static int nvmem_validate_keepouts(struc
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset,
 | 
			
		||||
-				   void *buf, size_t bytes)
 | 
			
		||||
-{
 | 
			
		||||
-	if (WARN_ON(bytes != ETH_ALEN))
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-	if (index)
 | 
			
		||||
-		eth_addr_add(buf, index);
 | 
			
		||||
-
 | 
			
		||||
-	return 0;
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset,
 | 
			
		||||
-				     void *buf, size_t bytes)
 | 
			
		||||
-{
 | 
			
		||||
-	u8 mac[ETH_ALEN];
 | 
			
		||||
-
 | 
			
		||||
-	if (WARN_ON(bytes != 3 * ETH_ALEN - 1))
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-	if (!mac_pton(buf, mac))
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-	if (index)
 | 
			
		||||
-		eth_addr_add(mac, index);
 | 
			
		||||
-
 | 
			
		||||
-	ether_addr_copy(buf, mac);
 | 
			
		||||
-
 | 
			
		||||
-	return 0;
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset,
 | 
			
		||||
-				   void *buf, size_t bytes)
 | 
			
		||||
-{
 | 
			
		||||
-	u8 mac[ETH_ALEN], *hexstr;
 | 
			
		||||
-	int i;
 | 
			
		||||
-
 | 
			
		||||
-	if (WARN_ON(bytes != 2 * ETH_ALEN))
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-	hexstr = (u8 *)buf;
 | 
			
		||||
-	for (i = 0; i < ETH_ALEN; i++) {
 | 
			
		||||
-		if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1]))
 | 
			
		||||
-			return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-		mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]);
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
-	if (index)
 | 
			
		||||
-		eth_addr_add(mac, index);
 | 
			
		||||
-
 | 
			
		||||
-	ether_addr_copy(buf, mac);
 | 
			
		||||
-
 | 
			
		||||
-	return 0;
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
 | 
			
		||||
 {
 | 
			
		||||
 	struct device *dev = &nvmem->dev;
 | 
			
		||||
@@ -895,24 +836,8 @@ static int nvmem_add_cells_from_dt(struc
 | 
			
		||||
 		if (nvmem->fixup_dt_cell_info)
 | 
			
		||||
 			nvmem->fixup_dt_cell_info(nvmem, &info);
 | 
			
		||||
 
 | 
			
		||||
-		if (of_device_is_compatible(np, "fixed-layout")) {
 | 
			
		||||
-			if (of_device_is_compatible(child, "mac-base")) {
 | 
			
		||||
-				if (info.bytes == ETH_ALEN) {
 | 
			
		||||
-					info.raw_len = info.bytes;
 | 
			
		||||
-					info.bytes = ETH_ALEN;
 | 
			
		||||
-					info.read_post_process = nvmem_mac_base_raw_read;
 | 
			
		||||
-				} else if (info.bytes == 2 * ETH_ALEN) {
 | 
			
		||||
-					info.raw_len = info.bytes;
 | 
			
		||||
-					info.bytes = ETH_ALEN;
 | 
			
		||||
-					info.read_post_process = nvmem_mac_base_hex_read;
 | 
			
		||||
-				} else if (info.bytes == 3 * ETH_ALEN - 1) {
 | 
			
		||||
-					info.raw_len = info.bytes;
 | 
			
		||||
-					info.bytes = ETH_ALEN;
 | 
			
		||||
-					info.read_post_process = nvmem_mac_base_ascii_read;
 | 
			
		||||
-				}
 | 
			
		||||
-
 | 
			
		||||
-			}
 | 
			
		||||
-		}
 | 
			
		||||
+		if (of_device_is_compatible(np, "fixed-layout"))
 | 
			
		||||
+			nvmem_layout_parse_mac_base(&info);
 | 
			
		||||
 
 | 
			
		||||
 		ret = nvmem_add_one_cell(nvmem, &info);
 | 
			
		||||
 		kfree(info.name);
 | 
			
		||||
--- a/drivers/nvmem/layouts.c
 | 
			
		||||
+++ b/drivers/nvmem/layouts.c
 | 
			
		||||
@@ -6,8 +6,11 @@
 | 
			
		||||
  * Author: Miquel Raynal <miquel.raynal@bootlin.com
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
+#include <linux/ctype.h>
 | 
			
		||||
 #include <linux/device.h>
 | 
			
		||||
 #include <linux/dma-mapping.h>
 | 
			
		||||
+#include <linux/etherdevice.h>
 | 
			
		||||
+#include <linux/if_ether.h>
 | 
			
		||||
 #include <linux/nvmem-consumer.h>
 | 
			
		||||
 #include <linux/nvmem-provider.h>
 | 
			
		||||
 #include <linux/of.h>
 | 
			
		||||
@@ -21,6 +24,83 @@
 | 
			
		||||
 #define to_nvmem_layout_device(_dev) \
 | 
			
		||||
 	container_of((_dev), struct nvmem_layout, dev)
 | 
			
		||||
 
 | 
			
		||||
+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset,
 | 
			
		||||
+				   void *buf, size_t bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	if (WARN_ON(bytes != ETH_ALEN))
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	if (index)
 | 
			
		||||
+		eth_addr_add(buf, index);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset,
 | 
			
		||||
+				     void *buf, size_t bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 mac[ETH_ALEN];
 | 
			
		||||
+
 | 
			
		||||
+	if (WARN_ON(bytes != 3 * ETH_ALEN - 1))
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	if (!mac_pton(buf, mac))
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	if (index)
 | 
			
		||||
+		eth_addr_add(mac, index);
 | 
			
		||||
+
 | 
			
		||||
+	ether_addr_copy(buf, mac);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset,
 | 
			
		||||
+				   void *buf, size_t bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 mac[ETH_ALEN], *hexstr;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	if (WARN_ON(bytes != 2 * ETH_ALEN))
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	hexstr = (u8 *)buf;
 | 
			
		||||
+	for (i = 0; i < ETH_ALEN; i++) {
 | 
			
		||||
+		if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1]))
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (index)
 | 
			
		||||
+		eth_addr_add(mac, index);
 | 
			
		||||
+
 | 
			
		||||
+	ether_addr_copy(buf, mac);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info)
 | 
			
		||||
+{
 | 
			
		||||
+	if (!of_device_is_compatible(info->np, "mac-base"))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	if (info->bytes == ETH_ALEN) {
 | 
			
		||||
+		info->raw_len = info->bytes;
 | 
			
		||||
+		info->bytes = ETH_ALEN;
 | 
			
		||||
+		info->read_post_process = nvmem_mac_base_raw_read;
 | 
			
		||||
+	} else if (info->bytes == 2 * ETH_ALEN) {
 | 
			
		||||
+		info->raw_len = info->bytes;
 | 
			
		||||
+		info->bytes = ETH_ALEN;
 | 
			
		||||
+		info->read_post_process = nvmem_mac_base_hex_read;
 | 
			
		||||
+	} else if (info->bytes == 3 * ETH_ALEN - 1) {
 | 
			
		||||
+		info->raw_len = info->bytes;
 | 
			
		||||
+		info->bytes = ETH_ALEN;
 | 
			
		||||
+		info->read_post_process = nvmem_mac_base_ascii_read;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+EXPORT_SYMBOL_GPL(nvmem_layout_parse_mac_base);
 | 
			
		||||
+
 | 
			
		||||
 static int nvmem_layout_bus_match(struct device *dev, const struct device_driver *drv)
 | 
			
		||||
 {
 | 
			
		||||
 	return of_driver_match_device(dev, drv);
 | 
			
		||||
--- a/include/linux/nvmem-provider.h
 | 
			
		||||
+++ b/include/linux/nvmem-provider.h
 | 
			
		||||
@@ -242,6 +242,8 @@ static inline void nvmem_layout_unregist
 | 
			
		||||
 
 | 
			
		||||
 #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)
 | 
			
		||||
 
 | 
			
		||||
+void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info);
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * of_nvmem_layout_get_container() - Get OF node of layout container
 | 
			
		||||
  *
 | 
			
		||||
@@ -254,6 +256,8 @@ struct device_node *of_nvmem_layout_get_
 | 
			
		||||
 
 | 
			
		||||
 #else  /* CONFIG_NVMEM && CONFIG_OF */
 | 
			
		||||
 
 | 
			
		||||
+static inline void nvmem_layout_parse_mac_base(struct nvmem_cell_info *info) {}
 | 
			
		||||
+
 | 
			
		||||
 static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem)
 | 
			
		||||
 {
 | 
			
		||||
 	return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,204 @@
 | 
			
		|||
From 38287e8ec5c0281377fc70f11f20bcd9986a05f5 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Christian Marangi <ansuelsmth@gmail.com>
 | 
			
		||||
Date: Mon, 3 Feb 2025 00:36:12 +0100
 | 
			
		||||
Subject: [PATCH 2/2] nvmem: layouts: add support for ascii-env driver
 | 
			
		||||
 | 
			
		||||
Add support for simple ASCII envirorment driver for NVMEM layouts.
 | 
			
		||||
 | 
			
		||||
It's very common for devices to store simple text file format in
 | 
			
		||||
partition for environment varibles. The most common pattern is variable
 | 
			
		||||
name, a delimiter and variable value all separated by a new line
 | 
			
		||||
character (\n).
 | 
			
		||||
 | 
			
		||||
This driver adds support for exporting such data and expose NVMEM cells
 | 
			
		||||
so they can be referenced by other drivers. This driver also supports
 | 
			
		||||
parsing mac-base NVMEM cells to parse ASCII or HEX mac address.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/layouts/Kconfig     |  13 +++
 | 
			
		||||
 drivers/nvmem/layouts/Makefile    |   1 +
 | 
			
		||||
 drivers/nvmem/layouts/ascii-env.c | 140 ++++++++++++++++++++++++++++++
 | 
			
		||||
 3 files changed, 154 insertions(+)
 | 
			
		||||
 create mode 100644 drivers/nvmem/layouts/ascii-env.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/layouts/Kconfig
 | 
			
		||||
+++ b/drivers/nvmem/layouts/Kconfig
 | 
			
		||||
@@ -37,6 +37,19 @@ config NVMEM_LAYOUT_U_BOOT_ENV
 | 
			
		||||
 
 | 
			
		||||
 	  If unsure, say N.
 | 
			
		||||
 
 | 
			
		||||
+config NVMEM_LAYOUT_ASCII_ENV
 | 
			
		||||
+	tristate "ASCII environment variables layout"
 | 
			
		||||
+	help
 | 
			
		||||
+	  It's very common for devices to store simple text file format in
 | 
			
		||||
+	  partition for environment varibles. The most common pattern is variable
 | 
			
		||||
+	  name, a delimiter and variable value all separated by a new line
 | 
			
		||||
+	  character (\n).
 | 
			
		||||
+	  This driver adds support for exporting such data and expose NVMEM cells
 | 
			
		||||
+	  so they can be referenced by other drivers. This driver also supports
 | 
			
		||||
+	  parsing mac-base NVMEM cells to parse ASCII or HEX mac address.
 | 
			
		||||
+
 | 
			
		||||
+	  If unsure, say N.
 | 
			
		||||
+
 | 
			
		||||
 endmenu
 | 
			
		||||
 
 | 
			
		||||
 endif
 | 
			
		||||
--- a/drivers/nvmem/layouts/Makefile
 | 
			
		||||
+++ b/drivers/nvmem/layouts/Makefile
 | 
			
		||||
@@ -6,3 +6,4 @@
 | 
			
		||||
 obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
 | 
			
		||||
 obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
 | 
			
		||||
 obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
 | 
			
		||||
+obj-$(CONFIG_NVMEM_LAYOUT_ASCII_ENV) += ascii-env.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/nvmem/layouts/ascii-env.c
 | 
			
		||||
@@ -0,0 +1,148 @@
 | 
			
		||||
+// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
+/*
 | 
			
		||||
+ * Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
 | 
			
		||||
+ *
 | 
			
		||||
+ * This borrow some parse logic from u-boot-env.
 | 
			
		||||
+ */
 | 
			
		||||
+#include <linux/nvmem-consumer.h>
 | 
			
		||||
+#include <linux/nvmem-provider.h>
 | 
			
		||||
+#include <linux/of.h>
 | 
			
		||||
+#include <linux/slab.h>
 | 
			
		||||
+
 | 
			
		||||
+struct ascii_env_match_data {
 | 
			
		||||
+	const char delim;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * Parse a buffer as an ASCII text with name delimiter value and each pattern separated
 | 
			
		||||
+ * with a new line char '\n'
 | 
			
		||||
+ * Example: (delimiter '=')
 | 
			
		||||
+ *   name=value\nname2=value2\n
 | 
			
		||||
+ *   2 Cell:
 | 
			
		||||
+ *   - name: value
 | 
			
		||||
+ *   - name2: value2
 | 
			
		||||
+ */
 | 
			
		||||
+static int ascii_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
 | 
			
		||||
+				 size_t data_len, const char delim)
 | 
			
		||||
+{
 | 
			
		||||
+	char *var, *value, *eq, *lf;
 | 
			
		||||
+	char *data = buf;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Warning the inner loop take care of replacing '\n'
 | 
			
		||||
+	 * with '\0', hence we can use strlen on value.
 | 
			
		||||
+	 */
 | 
			
		||||
+	for (var = data; var < data + data_len && *var;
 | 
			
		||||
+	     var = value + strlen(value) + 1) {
 | 
			
		||||
+		struct nvmem_cell_info info = {};
 | 
			
		||||
+		struct device_node *child;
 | 
			
		||||
+		const char *label;
 | 
			
		||||
+
 | 
			
		||||
+		eq = strchr(var, delim);
 | 
			
		||||
+		if (!eq)
 | 
			
		||||
+			break;
 | 
			
		||||
+		*eq = '\0';
 | 
			
		||||
+		value = eq + 1;
 | 
			
		||||
+
 | 
			
		||||
+		/* Replace '\n' with '\0' to use strlen for value */
 | 
			
		||||
+		lf = strchr(value, '\n');
 | 
			
		||||
+		if (!lf)
 | 
			
		||||
+			break;
 | 
			
		||||
+		*lf = '\0';
 | 
			
		||||
+
 | 
			
		||||
+		info.name = devm_kstrdup(dev, var, GFP_KERNEL);
 | 
			
		||||
+		if (!info.name)
 | 
			
		||||
+			return -ENOMEM;
 | 
			
		||||
+		info.offset = value - data;
 | 
			
		||||
+		info.bytes = strlen(value);
 | 
			
		||||
+		info.np = of_get_child_by_name(dev->of_node, info.name);
 | 
			
		||||
+		for_each_child_of_node(dev->of_node, child) {
 | 
			
		||||
+			if (!of_property_read_string(child, "label", &label) &&
 | 
			
		||||
+			    !strncmp(info.name, label, info.bytes))
 | 
			
		||||
+			    	info.np = child;
 | 
			
		||||
+			else if (of_node_name_eq(child, info.name))
 | 
			
		||||
+				info.np = child;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		nvmem_layout_parse_mac_base(&info);
 | 
			
		||||
+
 | 
			
		||||
+		nvmem_add_one_cell(nvmem, &info);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int ascii_env_add_cells(struct nvmem_layout *layout)
 | 
			
		||||
+{
 | 
			
		||||
+	struct nvmem_device *nvmem = layout->nvmem;
 | 
			
		||||
+	const struct ascii_env_match_data *data;
 | 
			
		||||
+	struct device *dev = &layout->dev;
 | 
			
		||||
+	size_t dev_size;
 | 
			
		||||
+	uint8_t *buf;
 | 
			
		||||
+	int bytes;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* Get the delimiter for name value pattern */
 | 
			
		||||
+	data = device_get_match_data(dev);
 | 
			
		||||
+
 | 
			
		||||
+	dev_size = nvmem_dev_size(nvmem);
 | 
			
		||||
+
 | 
			
		||||
+	buf = kzalloc(dev_size, GFP_KERNEL);
 | 
			
		||||
+	if (!buf) {
 | 
			
		||||
+		ret = -ENOMEM;
 | 
			
		||||
+		goto err_out;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
 | 
			
		||||
+	if (bytes < 0) {
 | 
			
		||||
+		ret = bytes;
 | 
			
		||||
+		goto err_kfree;
 | 
			
		||||
+	} else if (bytes != dev_size) {
 | 
			
		||||
+		ret = -EIO;
 | 
			
		||||
+		goto err_kfree;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	buf[dev_size - 1] = '\0';
 | 
			
		||||
+	ret = ascii_env_parse_cells(dev, nvmem, buf, dev_size, data->delim);
 | 
			
		||||
+
 | 
			
		||||
+err_kfree:
 | 
			
		||||
+	kfree(buf);
 | 
			
		||||
+err_out:
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int ascii_env_probe(struct nvmem_layout *layout)
 | 
			
		||||
+{
 | 
			
		||||
+	layout->add_cells = ascii_env_add_cells;
 | 
			
		||||
+
 | 
			
		||||
+	return nvmem_layout_register(layout);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void ascii_env_remove(struct nvmem_layout *layout)
 | 
			
		||||
+{
 | 
			
		||||
+	nvmem_layout_unregister(layout);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static const struct ascii_env_match_data ascii_env_eq = {
 | 
			
		||||
+	.delim = '=',
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const struct of_device_id ascii_env_of_match_table[] = {
 | 
			
		||||
+	{ .compatible = "ascii-eq-delim-env", .data = &ascii_env_eq, },
 | 
			
		||||
+	{},
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static struct nvmem_layout_driver ascii_env_layout = {
 | 
			
		||||
+	.driver = {
 | 
			
		||||
+		.name = "ascii-env-layout",
 | 
			
		||||
+		.of_match_table = ascii_env_of_match_table,
 | 
			
		||||
+	},
 | 
			
		||||
+	.probe = ascii_env_probe,
 | 
			
		||||
+	.remove = ascii_env_remove,
 | 
			
		||||
+};
 | 
			
		||||
+module_nvmem_layout_driver(ascii_env_layout);
 | 
			
		||||
+
 | 
			
		||||
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
 | 
			
		||||
+MODULE_LICENSE("GPL");
 | 
			
		||||
+MODULE_DEVICE_TABLE(of, ascii_env_of_match_table);
 | 
			
		||||
+MODULE_DESCRIPTION("NVMEM layout driver for ASCII environment variables");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,181 @@
 | 
			
		|||
From: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
To: Pavel Machek <pavel@ucw.cz>, Lee Jones <lee@kernel.org>,
 | 
			
		||||
	Rob Herring <robh@kernel.org>,
 | 
			
		||||
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
 | 
			
		||||
	Conor Dooley <conor+dt@kernel.org>,
 | 
			
		||||
	Jonathan Corbet <corbet@lwn.net>,
 | 
			
		||||
	Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>,
 | 
			
		||||
	linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
 | 
			
		||||
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
 | 
			
		||||
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | 
			
		||||
Subject: [PATCH v11 2/3] dt-bindings: leds: Add LED1202 LED Controller
 | 
			
		||||
Date: Wed, 18 Dec 2024 18:33:58 +0000	[thread overview]
 | 
			
		||||
Message-ID: <20241218183401.41687-3-vicentiu.galanopulo@remote-tech.co.uk> (raw)
 | 
			
		||||
In-Reply-To: <20241218183401.41687-1-vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
 | 
			
		||||
The LED1202 is a 12-channel low quiescent current LED driver with:
 | 
			
		||||
  * Supply range from 2.6 V to 5 V
 | 
			
		||||
  * 20 mA current capability per channel
 | 
			
		||||
  * 1.8 V compatible I2C control interface
 | 
			
		||||
  * 8-bit analog dimming individual control
 | 
			
		||||
  * 12-bit local PWM resolution
 | 
			
		||||
  * 8 programmable patterns
 | 
			
		||||
 | 
			
		||||
If the led node is present in the controller then the channel is
 | 
			
		||||
set to active.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | 
			
		||||
---
 | 
			
		||||
    v1: https://lore.kernel.org/lkml/ZnCnnQfwuRueCIQ0@admins-Air/T/
 | 
			
		||||
    v2: https://lore.kernel.org/all/ZniNdGgKyUMV-hjq@admins-Air/T/
 | 
			
		||||
    v3: https://lore.kernel.org/all/ZniNdGgKyUMV-hjq@admins-Air/T/
 | 
			
		||||
    
 | 
			
		||||
    Changes in v4:
 | 
			
		||||
      - remove label property, use devm_led_classdev_register_ext instead
 | 
			
		||||
    Changes in v3:
 | 
			
		||||
      - remove active property
 | 
			
		||||
    Changes in v2:
 | 
			
		||||
      - renamed label to remove color from it
 | 
			
		||||
      - add color property for each node
 | 
			
		||||
      - add function and function-enumerator property for each node
 | 
			
		||||
 | 
			
		||||
 .../devicetree/bindings/leds/st,led1202.yaml  | 132 ++++++++++++++++++
 | 
			
		||||
 1 file changed, 132 insertions(+)
 | 
			
		||||
 create mode 100644 Documentation/devicetree/bindings/leds/st,led1202.yaml
 | 
			
		||||
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/Documentation/devicetree/bindings/leds/st,led1202.yaml
 | 
			
		||||
@@ -0,0 +1,132 @@
 | 
			
		||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | 
			
		||||
+%YAML 1.2
 | 
			
		||||
+---
 | 
			
		||||
+$id: http://devicetree.org/schemas/leds/st,led1202.yaml#
 | 
			
		||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
 | 
			
		||||
+
 | 
			
		||||
+title: ST LED1202 LED controllers
 | 
			
		||||
+
 | 
			
		||||
+maintainers:
 | 
			
		||||
+  - Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
+
 | 
			
		||||
+description: |
 | 
			
		||||
+  The LED1202 is a 12-channel low quiescent current LED controller
 | 
			
		||||
+  programmable via I2C; The output current can be adjusted separately
 | 
			
		||||
+  for each channel by 8-bit analog and 12-bit digital dimming control.
 | 
			
		||||
+  Datasheet available at
 | 
			
		||||
+  https://www.st.com/en/power-management/led1202.html
 | 
			
		||||
+
 | 
			
		||||
+properties:
 | 
			
		||||
+  compatible:
 | 
			
		||||
+    const: st,led1202
 | 
			
		||||
+
 | 
			
		||||
+  reg:
 | 
			
		||||
+    maxItems: 1
 | 
			
		||||
+
 | 
			
		||||
+  "#address-cells":
 | 
			
		||||
+    const: 1
 | 
			
		||||
+
 | 
			
		||||
+  "#size-cells":
 | 
			
		||||
+    const: 0
 | 
			
		||||
+
 | 
			
		||||
+patternProperties:
 | 
			
		||||
+  "^led@[0-9a-f]$":
 | 
			
		||||
+    type: object
 | 
			
		||||
+    $ref: common.yaml#
 | 
			
		||||
+    unevaluatedProperties: false
 | 
			
		||||
+
 | 
			
		||||
+    properties:
 | 
			
		||||
+      reg:
 | 
			
		||||
+        minimum: 0
 | 
			
		||||
+        maximum: 11
 | 
			
		||||
+
 | 
			
		||||
+    required:
 | 
			
		||||
+      - reg
 | 
			
		||||
+
 | 
			
		||||
+required:
 | 
			
		||||
+  - compatible
 | 
			
		||||
+  - reg
 | 
			
		||||
+  - "#address-cells"
 | 
			
		||||
+  - "#size-cells"
 | 
			
		||||
+
 | 
			
		||||
+additionalProperties: false
 | 
			
		||||
+
 | 
			
		||||
+examples:
 | 
			
		||||
+  - |
 | 
			
		||||
+    #include <dt-bindings/leds/common.h>
 | 
			
		||||
+
 | 
			
		||||
+    i2c {
 | 
			
		||||
+        #address-cells = <1>;
 | 
			
		||||
+        #size-cells = <0>;
 | 
			
		||||
+
 | 
			
		||||
+        led-controller@58 {
 | 
			
		||||
+            compatible = "st,led1202";
 | 
			
		||||
+            reg = <0x58>;
 | 
			
		||||
+            #address-cells = <1>;
 | 
			
		||||
+            #size-cells = <0>;
 | 
			
		||||
+
 | 
			
		||||
+            led@0 {
 | 
			
		||||
+                reg = <0x0>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_RED>;
 | 
			
		||||
+                function-enumerator = <1>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@1 {
 | 
			
		||||
+                reg = <0x1>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_GREEN>;
 | 
			
		||||
+                function-enumerator = <2>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@2 {
 | 
			
		||||
+                reg = <0x2>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_BLUE>;
 | 
			
		||||
+                function-enumerator = <3>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@3 {
 | 
			
		||||
+                reg = <0x3>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_RED>;
 | 
			
		||||
+                function-enumerator = <4>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@4 {
 | 
			
		||||
+                reg = <0x4>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_GREEN>;
 | 
			
		||||
+                function-enumerator = <5>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@5 {
 | 
			
		||||
+                reg = <0x5>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_BLUE>;
 | 
			
		||||
+                function-enumerator = <6>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@6 {
 | 
			
		||||
+                reg = <0x6>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_RED>;
 | 
			
		||||
+                function-enumerator = <7>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@7 {
 | 
			
		||||
+                reg = <0x7>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_GREEN>;
 | 
			
		||||
+                function-enumerator = <8>;
 | 
			
		||||
+            };
 | 
			
		||||
+
 | 
			
		||||
+            led@8 {
 | 
			
		||||
+                reg = <0x8>;
 | 
			
		||||
+                function = LED_FUNCTION_STATUS;
 | 
			
		||||
+                color = <LED_COLOR_ID_BLUE>;
 | 
			
		||||
+                function-enumerator = <9>;
 | 
			
		||||
+            };
 | 
			
		||||
+        };
 | 
			
		||||
+    };
 | 
			
		||||
+...
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,513 @@
 | 
			
		|||
From: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
To: Pavel Machek <pavel@ucw.cz>, Lee Jones <lee@kernel.org>,
 | 
			
		||||
	Rob Herring <robh@kernel.org>,
 | 
			
		||||
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
 | 
			
		||||
	Conor Dooley <conor+dt@kernel.org>,
 | 
			
		||||
	Jonathan Corbet <corbet@lwn.net>,
 | 
			
		||||
	Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>,
 | 
			
		||||
	linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
 | 
			
		||||
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org
 | 
			
		||||
Subject: [PATCH v11 3/3] leds: Add LED1202 I2C driver
 | 
			
		||||
Date: Wed, 18 Dec 2024 18:33:59 +0000	[thread overview]
 | 
			
		||||
Message-ID: <20241218183401.41687-4-vicentiu.galanopulo@remote-tech.co.uk> (raw)
 | 
			
		||||
In-Reply-To: <20241218183401.41687-1-vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
 | 
			
		||||
The output current can be adjusted separately for each channel by 8-bit
 | 
			
		||||
analog (current sink input) and 12-bit digital (PWM) dimming control. The
 | 
			
		||||
LED1202 implements 12 low-side current generators with independent dimming
 | 
			
		||||
control.
 | 
			
		||||
Internal volatile memory allows the user to store up to 8 different patterns,
 | 
			
		||||
each pattern is a particular output configuration in terms of PWM
 | 
			
		||||
duty-cycle (on 4096 steps). Analog dimming (on 256 steps) is per channel but
 | 
			
		||||
common to all patterns. Each device tree LED node will have a corresponding
 | 
			
		||||
entry in /sys/class/leds with the label name. The brightness property
 | 
			
		||||
corresponds to the per channel analog dimming, while the patterns[1-8] to the
 | 
			
		||||
PWM dimming control.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Vicentiu Galanopulo <vicentiu.galanopulo@remote-tech.co.uk>
 | 
			
		||||
---
 | 
			
		||||
    Changes in v10:
 | 
			
		||||
      - update description help in Kconfig
 | 
			
		||||
      - move st1202_led and st1202_chip into one line, declaration and definition
 | 
			
		||||
    Changes in v9:
 | 
			
		||||
      - log errors directly in st1202_write_reg and st1202_read_reg
 | 
			
		||||
      - use mutex guards instead of lock/unlock
 | 
			
		||||
      - remove i2c_set_clientdata
 | 
			
		||||
    Changes in v7:
 | 
			
		||||
      - fix st1202_brightness_get() error: uninitialized symbol 'value'
 | 
			
		||||
    Changes in v6:
 | 
			
		||||
      - fix build error
 | 
			
		||||
    Changes in v5:
 | 
			
		||||
      - remove unused macros
 | 
			
		||||
      - switch to using devm_led_classdev_register_ext (struct st1202_led update)
 | 
			
		||||
      - add prescalar_to_milliseconds (convert [22..5660]ms to [0..255] reg value)
 | 
			
		||||
      - remove register range check in dt_init (range protected by yaml)
 | 
			
		||||
      - address all review comments in v4
 | 
			
		||||
    Changes in v4:
 | 
			
		||||
      - Remove attributes/extended attributes implementation
 | 
			
		||||
      - Use /sys/class/leds/<led>/hw_pattern (Pavel suggestion)
 | 
			
		||||
      - Implement review findings of Christophe JAILLET
 | 
			
		||||
    Changes in v3:
 | 
			
		||||
      - Rename all ll1202 to st1202, including driver file name
 | 
			
		||||
      - Convert all magic numbers to defines
 | 
			
		||||
      - Refactor the show/store callbacks as per Lee's and Thomas's review
 | 
			
		||||
      - Remove ll1202_get_channel and use dev_ext_attributes instead
 | 
			
		||||
      - Log all error values for all the functions
 | 
			
		||||
      - Use sysfs_emit for show callbacks
 | 
			
		||||
    Changes in v2:
 | 
			
		||||
      - Fix build error for device_attribute modes
 | 
			
		||||
 | 
			
		||||
 drivers/leds/Kconfig       |  10 +
 | 
			
		||||
 drivers/leds/Makefile      |   1 +
 | 
			
		||||
 drivers/leds/leds-st1202.c | 416 +++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 3 files changed, 427 insertions(+)
 | 
			
		||||
 create mode 100644 drivers/leds/leds-st1202.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/leds/Kconfig
 | 
			
		||||
+++ b/drivers/leds/Kconfig
 | 
			
		||||
@@ -931,6 +931,16 @@ config LEDS_LM36274
 | 
			
		||||
 	  Say Y to enable the LM36274 LED driver for TI LMU devices.
 | 
			
		||||
 	  This supports the LED device LM36274.
 | 
			
		||||
 
 | 
			
		||||
+config LEDS_ST1202
 | 
			
		||||
+	tristate "LED Support for STMicroelectronics LED1202 I2C chips"
 | 
			
		||||
+	depends on LEDS_CLASS
 | 
			
		||||
+	depends on I2C
 | 
			
		||||
+	depends on OF
 | 
			
		||||
+	select LEDS_TRIGGERS
 | 
			
		||||
+	help
 | 
			
		||||
+	  Say Y to enable support for LEDs connected to LED1202
 | 
			
		||||
+	  LED driver chips accessed via the I2C bus.
 | 
			
		||||
+
 | 
			
		||||
 config LEDS_TPS6105X
 | 
			
		||||
 	tristate "LED support for TI TPS6105X"
 | 
			
		||||
 	depends on LEDS_CLASS
 | 
			
		||||
--- a/drivers/leds/Makefile
 | 
			
		||||
+++ b/drivers/leds/Makefile
 | 
			
		||||
@@ -82,6 +82,7 @@ obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
 | 
			
		||||
 obj-$(CONFIG_LEDS_REGULATOR)		+= leds-regulator.o
 | 
			
		||||
 obj-$(CONFIG_LEDS_SC27XX_BLTC)		+= leds-sc27xx-bltc.o
 | 
			
		||||
 obj-$(CONFIG_LEDS_SUN50I_A100)		+= leds-sun50i-a100.o
 | 
			
		||||
+obj-$(CONFIG_LEDS_ST1202)		+= leds-st1202.o
 | 
			
		||||
 obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
 | 
			
		||||
 obj-$(CONFIG_LEDS_SYSCON)		+= leds-syscon.o
 | 
			
		||||
 obj-$(CONFIG_LEDS_TCA6507)		+= leds-tca6507.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/leds/leds-st1202.c
 | 
			
		||||
@@ -0,0 +1,416 @@
 | 
			
		||||
+// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
+/*
 | 
			
		||||
+ * LED driver for STMicroelectronics LED1202 chip
 | 
			
		||||
+ *
 | 
			
		||||
+ * Copyright (C) 2024 Remote-Tech Ltd. UK
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/cleanup.h>
 | 
			
		||||
+#include <linux/ctype.h>
 | 
			
		||||
+#include <linux/delay.h>
 | 
			
		||||
+#include <linux/err.h>
 | 
			
		||||
+#include <linux/gpio.h>
 | 
			
		||||
+#include <linux/i2c.h>
 | 
			
		||||
+#include <linux/leds.h>
 | 
			
		||||
+#include <linux/module.h>
 | 
			
		||||
+#include <linux/slab.h>
 | 
			
		||||
+#include <linux/string.h>
 | 
			
		||||
+
 | 
			
		||||
+#define ST1202_CHAN_DISABLE_ALL            0x00
 | 
			
		||||
+#define ST1202_CHAN_ENABLE_HIGH            0x03
 | 
			
		||||
+#define ST1202_CHAN_ENABLE_LOW             0x02
 | 
			
		||||
+#define ST1202_CONFIG_REG                  0x04
 | 
			
		||||
+/* PATS: Pattern sequence feature enable */
 | 
			
		||||
+#define ST1202_CONFIG_REG_PATS             BIT(7)
 | 
			
		||||
+/* PATSR: Pattern sequence runs (self-clear when sequence is finished) */
 | 
			
		||||
+#define ST1202_CONFIG_REG_PATSR            BIT(6)
 | 
			
		||||
+#define ST1202_CONFIG_REG_SHFT             BIT(3)
 | 
			
		||||
+#define ST1202_DEV_ENABLE                  0x01
 | 
			
		||||
+#define ST1202_DEV_ENABLE_ON               BIT(0)
 | 
			
		||||
+#define ST1202_DEV_ENABLE_RESET            BIT(7)
 | 
			
		||||
+#define ST1202_DEVICE_ID                   0x00
 | 
			
		||||
+#define ST1202_ILED_REG0                   0x09
 | 
			
		||||
+#define ST1202_MAX_LEDS                    12
 | 
			
		||||
+#define ST1202_MAX_PATTERNS                8
 | 
			
		||||
+#define ST1202_MILLIS_PATTERN_DUR_MAX      5660
 | 
			
		||||
+#define ST1202_MILLIS_PATTERN_DUR_MIN      22
 | 
			
		||||
+#define ST1202_PATTERN_DUR                 0x16
 | 
			
		||||
+#define ST1202_PATTERN_PWM                 0x1E
 | 
			
		||||
+#define ST1202_PATTERN_REP                 0x15
 | 
			
		||||
+
 | 
			
		||||
+struct st1202_led {
 | 
			
		||||
+	struct fwnode_handle *fwnode;
 | 
			
		||||
+	struct led_classdev led_cdev;
 | 
			
		||||
+	struct st1202_chip *chip;
 | 
			
		||||
+	bool is_active;
 | 
			
		||||
+	int led_num;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct st1202_chip {
 | 
			
		||||
+	struct i2c_client *client;
 | 
			
		||||
+	struct mutex lock;
 | 
			
		||||
+	struct st1202_led leds[ST1202_MAX_LEDS];
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static struct st1202_led *cdev_to_st1202_led(struct led_classdev *cdev)
 | 
			
		||||
+{
 | 
			
		||||
+	return container_of(cdev, struct st1202_led, led_cdev);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_read_reg(struct st1202_chip *chip, int reg, uint8_t *val)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device *dev = &chip->client->dev;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = i2c_smbus_read_byte_data(chip->client, reg);
 | 
			
		||||
+	if (ret < 0) {
 | 
			
		||||
+		dev_err(dev, "Failed to read register [0x%x]: %d\n", reg, ret);
 | 
			
		||||
+		return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	*val = (uint8_t)ret;
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_write_reg(struct st1202_chip *chip, int reg, uint8_t val)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device *dev = &chip->client->dev;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = i2c_smbus_write_byte_data(chip->client, reg, val);
 | 
			
		||||
+	if (ret != 0)
 | 
			
		||||
+		dev_err(dev, "Failed to write %d to register [0x%x]: %d\n", val, reg, ret);
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static uint8_t st1202_prescalar_to_miliseconds(unsigned int value)
 | 
			
		||||
+{
 | 
			
		||||
+	return value / ST1202_MILLIS_PATTERN_DUR_MIN - 1;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_pwm_pattern_write(struct st1202_chip *chip, int led_num,
 | 
			
		||||
+				int pattern, unsigned int value)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 value_l, value_h;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	value_l = (u8)value;
 | 
			
		||||
+	value_h = (u8)(value >> 8);
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 *  Datasheet: Register address low = 1Eh + 2*(xh) + 18h*(yh),
 | 
			
		||||
+	 *  where x is the channel number (led number) in hexadecimal (x = 00h .. 0Bh)
 | 
			
		||||
+	 *  and y is the pattern number in hexadecimal (y = 00h .. 07h)
 | 
			
		||||
+	 */
 | 
			
		||||
+	ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + (led_num * 2) + 0x18 * pattern),
 | 
			
		||||
+				value_l);
 | 
			
		||||
+	if (ret != 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Datasheet: Register address high = 1Eh + 01h + 2(xh) +18h*(yh),
 | 
			
		||||
+	 * where x is the channel number in hexadecimal (x = 00h .. 0Bh)
 | 
			
		||||
+	 * and y is the pattern number in hexadecimal (y = 00h .. 07h)
 | 
			
		||||
+	 */
 | 
			
		||||
+	ret = st1202_write_reg(chip, (ST1202_PATTERN_PWM + 0x1 + (led_num * 2) + 0x18 * pattern),
 | 
			
		||||
+				value_h);
 | 
			
		||||
+	if (ret != 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_duration_pattern_write(struct st1202_chip *chip, int pattern,
 | 
			
		||||
+					unsigned int value)
 | 
			
		||||
+{
 | 
			
		||||
+	return st1202_write_reg(chip, (ST1202_PATTERN_DUR + pattern),
 | 
			
		||||
+				st1202_prescalar_to_miliseconds(value));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void st1202_brightness_set(struct led_classdev *led_cdev,
 | 
			
		||||
+				enum led_brightness value)
 | 
			
		||||
+{
 | 
			
		||||
+	struct st1202_led *led = cdev_to_st1202_led(led_cdev);
 | 
			
		||||
+	struct st1202_chip *chip = led->chip;
 | 
			
		||||
+
 | 
			
		||||
+	guard(mutex)(&chip->lock);
 | 
			
		||||
+
 | 
			
		||||
+	st1202_write_reg(chip, ST1202_ILED_REG0 + led->led_num, value);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static enum led_brightness st1202_brightness_get(struct led_classdev *led_cdev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct st1202_led *led = cdev_to_st1202_led(led_cdev);
 | 
			
		||||
+	struct st1202_chip *chip = led->chip;
 | 
			
		||||
+	u8 value = 0;
 | 
			
		||||
+
 | 
			
		||||
+	guard(mutex)(&chip->lock);
 | 
			
		||||
+
 | 
			
		||||
+	st1202_read_reg(chip, ST1202_ILED_REG0 + led->led_num, &value);
 | 
			
		||||
+
 | 
			
		||||
+	return value;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_channel_set(struct st1202_chip *chip, int led_num, bool active)
 | 
			
		||||
+{
 | 
			
		||||
+	u8 chan_low, chan_high;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	guard(mutex)(&chip->lock);
 | 
			
		||||
+
 | 
			
		||||
+	if (led_num <= 7) {
 | 
			
		||||
+		ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_LOW, &chan_low);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+
 | 
			
		||||
+		chan_low = active ? chan_low | BIT(led_num) : chan_low & ~BIT(led_num);
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, chan_low);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+
 | 
			
		||||
+	} else {
 | 
			
		||||
+		ret = st1202_read_reg(chip, ST1202_CHAN_ENABLE_HIGH, &chan_high);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+
 | 
			
		||||
+		chan_high = active ? chan_high | (BIT(led_num) >> 8) :
 | 
			
		||||
+					chan_high & ~(BIT(led_num) >> 8);
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, chan_high);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_led_set(struct led_classdev *ldev, enum led_brightness value)
 | 
			
		||||
+{
 | 
			
		||||
+	struct st1202_led *led = cdev_to_st1202_led(ldev);
 | 
			
		||||
+	struct st1202_chip *chip = led->chip;
 | 
			
		||||
+
 | 
			
		||||
+	return st1202_channel_set(chip, led->led_num, value == LED_OFF ? false : true);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_led_pattern_clear(struct led_classdev *ldev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct st1202_led *led = cdev_to_st1202_led(ldev);
 | 
			
		||||
+	struct st1202_chip *chip = led->chip;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	guard(mutex)(&chip->lock);
 | 
			
		||||
+
 | 
			
		||||
+	for (int patt = 0; patt < ST1202_MAX_PATTERNS; patt++) {
 | 
			
		||||
+		ret = st1202_pwm_pattern_write(chip, led->led_num, patt, LED_OFF);
 | 
			
		||||
+		if (ret != 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_duration_pattern_write(chip, patt, ST1202_MILLIS_PATTERN_DUR_MIN);
 | 
			
		||||
+		if (ret != 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_led_pattern_set(struct led_classdev *ldev,
 | 
			
		||||
+				struct led_pattern *pattern,
 | 
			
		||||
+				u32 len, int repeat)
 | 
			
		||||
+{
 | 
			
		||||
+	struct st1202_led *led = cdev_to_st1202_led(ldev);
 | 
			
		||||
+	struct st1202_chip *chip = led->chip;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	if (len > ST1202_MAX_PATTERNS)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	guard(mutex)(&chip->lock);
 | 
			
		||||
+
 | 
			
		||||
+	for (int patt = 0; patt < len; patt++) {
 | 
			
		||||
+		if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
 | 
			
		||||
+				pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
 | 
			
		||||
+		if (ret != 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_duration_pattern_write(chip, patt, pattern[patt].delta_t);
 | 
			
		||||
+		if (ret != 0)
 | 
			
		||||
+			return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_PATTERN_REP, repeat);
 | 
			
		||||
+	if (ret != 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_CONFIG_REG, (ST1202_CONFIG_REG_PATSR |
 | 
			
		||||
+							ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_SHFT));
 | 
			
		||||
+	if (ret != 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_dt_init(struct st1202_chip *chip)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device *dev = &chip->client->dev;
 | 
			
		||||
+	struct st1202_led *led;
 | 
			
		||||
+	int err, reg;
 | 
			
		||||
+
 | 
			
		||||
+	for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
 | 
			
		||||
+		struct led_init_data init_data = {};
 | 
			
		||||
+
 | 
			
		||||
+		err = of_property_read_u32(child, "reg", ®);
 | 
			
		||||
+		if (err)
 | 
			
		||||
+			return dev_err_probe(dev, err, "Invalid register\n");
 | 
			
		||||
+
 | 
			
		||||
+		led = &chip->leds[reg];
 | 
			
		||||
+		led->is_active = true;
 | 
			
		||||
+		led->fwnode = of_fwnode_handle(child);
 | 
			
		||||
+
 | 
			
		||||
+		led->led_cdev.max_brightness = U8_MAX;
 | 
			
		||||
+		led->led_cdev.brightness_set_blocking = st1202_led_set;
 | 
			
		||||
+		led->led_cdev.pattern_set = st1202_led_pattern_set;
 | 
			
		||||
+		led->led_cdev.pattern_clear = st1202_led_pattern_clear;
 | 
			
		||||
+		led->led_cdev.default_trigger = "pattern";
 | 
			
		||||
+
 | 
			
		||||
+		init_data.fwnode = led->fwnode;
 | 
			
		||||
+		init_data.devicename = "st1202";
 | 
			
		||||
+		init_data.default_label = ":";
 | 
			
		||||
+
 | 
			
		||||
+		err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data);
 | 
			
		||||
+		if (err < 0)
 | 
			
		||||
+			return dev_err_probe(dev, err, "Failed to register LED class device\n");
 | 
			
		||||
+
 | 
			
		||||
+		led->led_cdev.brightness_set = st1202_brightness_set;
 | 
			
		||||
+		led->led_cdev.brightness_get = st1202_brightness_get;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_setup(struct st1202_chip *chip)
 | 
			
		||||
+{
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	guard(mutex)(&chip->lock);
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Once the supply voltage is applied, the LED1202 executes some internal checks,
 | 
			
		||||
+	 * afterwords it stops the oscillator and puts the internal LDO in quiescent mode.
 | 
			
		||||
+	 * To start the device, EN bit must be set inside the “Device Enable” register at
 | 
			
		||||
+	 * address 01h. As soon as EN is set, the LED1202 loads the adjustment parameters
 | 
			
		||||
+	 * from the internal non-volatile memory and performs an auto-calibration procedure
 | 
			
		||||
+	 * in order to increase the output current precision.
 | 
			
		||||
+	 * Such initialization lasts about 6.5 ms.
 | 
			
		||||
+	 */
 | 
			
		||||
+
 | 
			
		||||
+	/* Reset the chip during setup */
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_RESET);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* Enable phase-shift delay feature */
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* Enable the device */
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_DEV_ENABLE, ST1202_DEV_ENABLE_ON);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* Duration of initialization */
 | 
			
		||||
+	usleep_range(6500, 10000);
 | 
			
		||||
+
 | 
			
		||||
+	/* Deactivate all LEDS (channels) and activate only the ones found in Device Tree */
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_LOW, ST1202_CHAN_DISABLE_ALL);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_CHAN_ENABLE_HIGH, ST1202_CHAN_DISABLE_ALL);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = st1202_write_reg(chip, ST1202_CONFIG_REG,
 | 
			
		||||
+				ST1202_CONFIG_REG_PATS | ST1202_CONFIG_REG_PATSR);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int st1202_probe(struct i2c_client *client)
 | 
			
		||||
+{
 | 
			
		||||
+	struct st1202_chip *chip;
 | 
			
		||||
+	struct st1202_led *led;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 | 
			
		||||
+		return dev_err_probe(&client->dev, -EIO, "SMBUS Byte Data not Supported\n");
 | 
			
		||||
+
 | 
			
		||||
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 | 
			
		||||
+	if (!chip)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+
 | 
			
		||||
+	devm_mutex_init(&client->dev, &chip->lock);
 | 
			
		||||
+	chip->client = client;
 | 
			
		||||
+
 | 
			
		||||
+	ret = st1202_dt_init(chip);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	ret = st1202_setup(chip);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	for (int i = 0; i < ST1202_MAX_LEDS; i++) {
 | 
			
		||||
+		led = &chip->leds[i];
 | 
			
		||||
+		led->chip = chip;
 | 
			
		||||
+		led->led_num = i;
 | 
			
		||||
+
 | 
			
		||||
+		if (!led->is_active)
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_channel_set(led->chip, led->led_num, true);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return dev_err_probe(&client->dev, ret,
 | 
			
		||||
+					"Failed to activate LED channel\n");
 | 
			
		||||
+
 | 
			
		||||
+		ret = st1202_led_pattern_clear(&led->led_cdev);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return dev_err_probe(&client->dev, ret,
 | 
			
		||||
+					"Failed to clear LED pattern\n");
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static const struct i2c_device_id st1202_id[] = {
 | 
			
		||||
+	{ "st1202-i2c" },
 | 
			
		||||
+	{ /* sentinel */ }
 | 
			
		||||
+};
 | 
			
		||||
+MODULE_DEVICE_TABLE(i2c, st1202_id);
 | 
			
		||||
+
 | 
			
		||||
+static const struct of_device_id st1202_dt_ids[] = {
 | 
			
		||||
+	{ .compatible = "st,led1202" },
 | 
			
		||||
+	{ /* sentinel */ }
 | 
			
		||||
+};
 | 
			
		||||
+MODULE_DEVICE_TABLE(of, st1202_dt_ids);
 | 
			
		||||
+
 | 
			
		||||
+static struct i2c_driver st1202_driver = {
 | 
			
		||||
+	.driver = {
 | 
			
		||||
+		.name = "leds-st1202",
 | 
			
		||||
+		.of_match_table = of_match_ptr(st1202_dt_ids),
 | 
			
		||||
+	},
 | 
			
		||||
+	.probe = st1202_probe,
 | 
			
		||||
+	.id_table = st1202_id,
 | 
			
		||||
+};
 | 
			
		||||
+module_i2c_driver(st1202_driver);
 | 
			
		||||
+
 | 
			
		||||
+MODULE_AUTHOR("Remote Tech LTD");
 | 
			
		||||
+MODULE_DESCRIPTION("STMicroelectronics LED1202 : 12-channel constant current LED driver");
 | 
			
		||||
+MODULE_LICENSE("GPL");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
From e3da313ebcace17f1227566fe1b0d0c3883061f9 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Manuel Fombuena <fombuena@outlook.com>
 | 
			
		||||
Date: Fri, 17 Jan 2025 12:31:49 +0000
 | 
			
		||||
Subject: [PATCH 1/5] leds: leds-st1202: fix NULL pointer access on race
 | 
			
		||||
 condition
 | 
			
		||||
 | 
			
		||||
st1202_dt_init() calls devm_led_classdev_register_ext() before the
 | 
			
		||||
internal data structures are properly setup, so the leds become visible
 | 
			
		||||
to user space while being partially initialized, leading to a window
 | 
			
		||||
where trying to access them causes a NULL pointer access.
 | 
			
		||||
 | 
			
		||||
This change moves devm_led_classdev_register_ext() to the last thing to
 | 
			
		||||
happen during initialization to eliminate it.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/leds/leds-st1202.c | 21 ++++++++++-----------
 | 
			
		||||
 1 file changed, 10 insertions(+), 11 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/leds/leds-st1202.c
 | 
			
		||||
+++ b/drivers/leds/leds-st1202.c
 | 
			
		||||
@@ -261,8 +261,6 @@ static int st1202_dt_init(struct st1202_
 | 
			
		||||
 	int err, reg;
 | 
			
		||||
 
 | 
			
		||||
 	for_each_available_child_of_node_scoped(dev_of_node(dev), child) {
 | 
			
		||||
-		struct led_init_data init_data = {};
 | 
			
		||||
-
 | 
			
		||||
 		err = of_property_read_u32(child, "reg", ®);
 | 
			
		||||
 		if (err)
 | 
			
		||||
 			return dev_err_probe(dev, err, "Invalid register\n");
 | 
			
		||||
@@ -276,15 +274,6 @@ static int st1202_dt_init(struct st1202_
 | 
			
		||||
 		led->led_cdev.pattern_set = st1202_led_pattern_set;
 | 
			
		||||
 		led->led_cdev.pattern_clear = st1202_led_pattern_clear;
 | 
			
		||||
 		led->led_cdev.default_trigger = "pattern";
 | 
			
		||||
-
 | 
			
		||||
-		init_data.fwnode = led->fwnode;
 | 
			
		||||
-		init_data.devicename = "st1202";
 | 
			
		||||
-		init_data.default_label = ":";
 | 
			
		||||
-
 | 
			
		||||
-		err = devm_led_classdev_register_ext(dev, &led->led_cdev, &init_data);
 | 
			
		||||
-		if (err < 0)
 | 
			
		||||
-			return dev_err_probe(dev, err, "Failed to register LED class device\n");
 | 
			
		||||
-
 | 
			
		||||
 		led->led_cdev.brightness_set = st1202_brightness_set;
 | 
			
		||||
 		led->led_cdev.brightness_get = st1202_brightness_get;
 | 
			
		||||
 	}
 | 
			
		||||
@@ -368,6 +357,7 @@ static int st1202_probe(struct i2c_clien
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
 	for (int i = 0; i < ST1202_MAX_LEDS; i++) {
 | 
			
		||||
+		struct led_init_data init_data = {};
 | 
			
		||||
 		led = &chip->leds[i];
 | 
			
		||||
 		led->chip = chip;
 | 
			
		||||
 		led->led_num = i;
 | 
			
		||||
@@ -384,6 +374,15 @@ static int st1202_probe(struct i2c_clien
 | 
			
		||||
 		if (ret < 0)
 | 
			
		||||
 			return dev_err_probe(&client->dev, ret,
 | 
			
		||||
 					"Failed to clear LED pattern\n");
 | 
			
		||||
+
 | 
			
		||||
+		init_data.fwnode = led->fwnode;
 | 
			
		||||
+		init_data.devicename = "st1202";
 | 
			
		||||
+		init_data.default_label = ":";
 | 
			
		||||
+
 | 
			
		||||
+		ret = devm_led_classdev_register_ext(&client->dev, &led->led_cdev, &init_data);
 | 
			
		||||
+		if (ret < 0)
 | 
			
		||||
+			return dev_err_probe(&client->dev, ret,
 | 
			
		||||
+					"Failed to register LED class device\n");
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue